Class: OAuth2::Client

Inherits:
Object
  • Object
show all
Includes:
FilteredAttributes
Defined in:
lib/oauth2/client.rb

Overview

The OAuth2::Client class

Constant Summary collapse

RESERVED_REQ_KEYS =

rubocop:disable Metrics/ClassLength

%w[body headers params redirect_count].freeze
RESERVED_PARAM_KEYS =
(RESERVED_REQ_KEYS + %w[parse snaky snaky_hash_klass token_method]).freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from FilteredAttributes

included, #inspect

Constructor Details

#initialize(client_id, client_secret, options = {}) {|builder| ... } ⇒ Client

Initializes a new OAuth2::Client instance using the Client ID and Client Secret registered to your application.

Parameters:

  • client_id (String)

    the client_id value

  • client_secret (String)

    the client_secret value

  • options (Hash) (defaults to: {})

    the options to configure the client

Options Hash (options):

  • :site (String)

    the OAuth2 provider site host

  • :authorize_url (String) — default: '/oauth/authorize'

    absolute or relative URL path to the Authorization endpoint

  • :revoke_url (String) — default: '/oauth/revoke'

    absolute or relative URL path to the Revoke endpoint

  • :token_url (String) — default: '/oauth/token'

    absolute or relative URL path to the Token endpoint

  • :token_method (Symbol) — default: :post

    HTTP method to use to request token (:get, :post, :post_with_query_string)

  • :auth_scheme (Symbol) — default: :basic_auth

    the authentication scheme (:basic_auth, :request_body, :tls_client_auth, :private_key_jwt)

  • :connection_opts (Hash) — default: {}

    Hash of connection options to pass to initialize Faraday

  • :raise_errors (Boolean) — default: true

    whether to raise an OAuth2::Error on responses with 400+ status codes

  • :max_redirects (Integer) — default: 5

    maximum number of redirects to follow

  • :logger (Logger) — default: ::Logger.new($stdout)

    Logger instance for HTTP request/response output; requires OAUTH_DEBUG to be true

  • :access_token_class (Class) — default: AccessToken

    class to use for access tokens; you can subclass OAuth2::AccessToken, @version 2.0+

  • :ssl (Hash)

    SSL options for Faraday

Yields:

  • (builder)

    The Faraday connection builder



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/oauth2/client.rb', line 50

def initialize(client_id, client_secret, options = {}, &block)
  opts = options.dup
  @id = client_id
  @secret = client_secret
  @site = opts.delete(:site)
  ssl = opts.delete(:ssl)
  warn("OAuth2::Client#initialize argument `extract_access_token` will be removed in oauth2 v3. Refactor to use `access_token_class`.") if opts[:extract_access_token]
  @options = {
    authorize_url: "oauth/authorize",
    revoke_url: "oauth/revoke",
    token_url: "oauth/token",
    token_method: :post,
    auth_scheme: :basic_auth,
    connection_opts: {},
    connection_build: block,
    max_redirects: 5,
    raise_errors: true,
    logger: ::Logger.new($stdout),
    access_token_class: AccessToken,
  }.merge(opts)
  @options[:connection_opts][:ssl] = ssl if ssl
end

Instance Attribute Details

#connectionFaraday::Connection

The Faraday connection object

Returns:

  • (Faraday::Connection)

    the initialized Faraday connection



85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/oauth2/client.rb', line 85

def connection
  @connection ||=
    Faraday.new(site, options[:connection_opts]) do |builder|
      oauth_debug_logging(builder)
      if options[:connection_build]
        options[:connection_build].call(builder)
      else
        builder.request(:url_encoded)             # form-encode POST params
        builder.adapter(Faraday.default_adapter)  # make requests with Net::HTTP
      end
    end
end

#idObject (readonly)

Returns the value of attribute id.



26
27
28
# File 'lib/oauth2/client.rb', line 26

def id
  @id
end

#optionsObject

Returns the value of attribute options.



27
28
29
# File 'lib/oauth2/client.rb', line 27

def options
  @options
end

#secretObject (readonly)

Returns the value of attribute secret.



26
27
28
# File 'lib/oauth2/client.rb', line 26

def secret
  @secret
end

#siteObject

Returns the value of attribute site.



26
27
28
# File 'lib/oauth2/client.rb', line 26

def site
  @site
end

Instance Method Details

#assertionOAuth2::Strategy::Assertion

The Assertion strategy

This allows for assertion-based authentication where an identity provider asserts the identity of the user or client application seeking access.



314
315
316
# File 'lib/oauth2/client.rb', line 314

def assertion
  @assertion ||= OAuth2::Strategy::Assertion.new(self)
end

#auth_codeObject

The Authorization Code strategy



280
281
282
# File 'lib/oauth2/client.rb', line 280

def auth_code
  @auth_code ||= OAuth2::Strategy::AuthCode.new(self)
end

#authorize_url(params = {}) ⇒ String

The authorize endpoint URL of the OAuth2 provider

Parameters:

  • params (Hash) (defaults to: {})

    additional query parameters

Returns:

  • (String)

    the constructed authorize URL



102
103
104
105
# File 'lib/oauth2/client.rb', line 102

def authorize_url(params = {})
  params = (params || {}).merge(redirection_params)
  connection.build_url(options[:authorize_url], params).to_s
end

#client_credentialsObject

The Client Credentials strategy



301
302
303
# File 'lib/oauth2/client.rb', line 301

def client_credentials
  @client_credentials ||= OAuth2::Strategy::ClientCredentials.new(self)
end

#get_token(params, access_token_opts = {}, extract_access_token = nil) {|opts| ... } ⇒ AccessToken?

Note:

The extract_access_token parameter is deprecated and will be removed in oauth2 v3. Use access_token_class on initialization instead.

Retrieves an access token from the token endpoint using the specified parameters

Examples:

client.get_token(
  'grant_type' => 'authorization_code',
  'code' => 'auth_code_value',
  'headers' => {'Authorization' => 'Basic ...'}
)

Parameters:

  • params (Hash)

    a Hash of params for the token endpoint

    • params can include a ‘headers’ key with a Hash of request headers

    • params can include a ‘parse’ key with the Symbol name of response parsing strategy (default: :automatic)

    • params can include a ‘snaky’ key to control snake_case conversion (default: false)

  • access_token_opts (Hash) (defaults to: {})

    options that will be passed to the AccessToken initialization

  • extract_access_token (Proc) (defaults to: nil)

    (deprecated) a proc that can extract the access token from the response

Yields:

  • (opts)

    The block is passed the options being used to make the request

Yield Parameters:

  • opts (Hash)

    options being passed to the http library

Returns:

  • (AccessToken, nil)

    the initialized AccessToken instance, or nil if token extraction fails and raise_errors is false



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/oauth2/client.rb', line 208

def get_token(params, access_token_opts = {}, extract_access_token = nil, &block)
  warn("OAuth2::Client#get_token argument `extract_access_token` will be removed in oauth2 v3. Refactor to use `access_token_class` on #initialize.") if extract_access_token
  extract_access_token ||= options[:extract_access_token]
  req_opts = params_to_req_opts(params)
  response = request(http_method, token_url, req_opts, &block)

  # In v1.4.x, the deprecated extract_access_token option retrieves the token from the response.
  # We preserve this behavior here, but a custom access_token_class that implements #from_hash
  # should be used instead.
  if extract_access_token
    parse_response_legacy(response, access_token_opts, extract_access_token)
  else
    parse_response(response, access_token_opts)
  end
end

#http_methodSymbol

The HTTP Method of the request

Returns:

  • (Symbol)

    HTTP verb, one of [:get, :post, :put, :delete]



270
271
272
273
274
275
# File 'lib/oauth2/client.rb', line 270

def http_method
  http_meth = options[:token_method].to_sym
  return :post if http_meth == :post_with_query_string

  http_meth
end

#implicitObject

The Implicit strategy



287
288
289
# File 'lib/oauth2/client.rb', line 287

def implicit
  @implicit ||= OAuth2::Strategy::Implicit.new(self)
end

#passwordObject

The Resource Owner Password Credentials strategy



294
295
296
# File 'lib/oauth2/client.rb', line 294

def password
  @password ||= OAuth2::Strategy::Password.new(self)
end

#redirection_paramsHash

The redirect_uri parameters, if configured

The redirect_uri query parameter is OPTIONAL (though encouraged) when requesting authorization. If it is provided at authorization time it MUST also be provided with the token exchange request.

Providing :redirect_uri to the OAuth2::Client instantiation will take care of managing this.



335
336
337
338
339
340
341
# File 'lib/oauth2/client.rb', line 335

def redirection_params
  if options[:redirect_uri]
    {"redirect_uri" => options[:redirect_uri]}
  else
    {}
  end
end

#request(verb, url, req_opts = {}) {|req| ... } ⇒ OAuth2::Response

Makes a request relative to the specified site root.

Updated HTTP 1.1 specification (IETF RFC 7231) relaxed the original constraint (IETF RFC 2616),

allowing the use of relative URLs in Location headers.

Parameters:

  • verb (Symbol)

    one of [:get, :post, :put, :delete]

  • url (String)

    URL path of request

  • req_opts (Hash) (defaults to: {})

    the options to make the request with

Options Hash (req_opts):

  • :params (Hash)

    additional query parameters for the URL of the request

  • :body (Hash, String)

    the body of the request

  • :headers (Hash)

    http request headers

  • :raise_errors (Boolean)

    whether to raise an OAuth2::Error on 400+ status code response for this request. Overrides the client instance setting.

  • :parse (Symbol)

    @see Response::initialize

  • :snaky (Boolean) — default: true

    @see Response::initialize

Yields:

  • (req)

    The block is passed the request being made, allowing customization

Yield Parameters:

  • req (Faraday::Request)

    The request object that can be modified

Returns:

See Also:



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/oauth2/client.rb', line 146

def request(verb, url, req_opts = {}, &block)
  response = execute_request(verb, url, req_opts, &block)
  status = response.status

  case status
  when 301, 302, 303, 307
    req_opts[:redirect_count] ||= 0
    req_opts[:redirect_count] += 1
    return response if req_opts[:redirect_count] > options[:max_redirects]

    if status == 303
      verb = :get
      req_opts.delete(:body)
    end
    location = response.headers["location"]
    if location
      full_location = response.response.env.url.merge(location)
      request(verb, full_location, req_opts)
    else
      error = Error.new(response)
      raise(error, "Got #{status} status code, but no Location header was present")
    end
  when 200..299, 300..399
    # on non-redirecting 3xx statuses, return the response
    response
  when 400..599
    if req_opts.fetch(:raise_errors, options[:raise_errors])
      error = Error.new(response)
      raise(error)
    end

    response
  else
    error = Error.new(response)
    raise(error, "Unhandled status code value of #{status}")
  end
end

#revoke_token(token, token_type_hint = nil, params = {}) {|req| ... } ⇒ OAuth2::Response

Note:

If the token passed to the request is an access token, the server MAY revoke the respective refresh token as well.

Note:

If the token passed to the request is a refresh token and the authorization server supports the revocation of access tokens, then the authorization server SHOULD also invalidate all access tokens based on the same authorization grant

Note:

If the server responds with HTTP status code 503, your code must assume the token still exists and may retry after a reasonable delay. The server may include a “Retry-After” header in the response to indicate how long the service is expected to be unavailable to the requesting client.

Makes a request to revoke a token at the authorization server

Parameters:

  • token (String)

    The token to be revoked

  • token_type_hint (String, nil) (defaults to: nil)

    A hint about the type of the token being revoked (e.g., ‘access_token’ or ‘refresh_token’)

  • params (Hash) (defaults to: {})

    additional parameters for the token revocation

Options Hash (params):

  • :parse (Symbol) — default: :automatic

    parsing strategy for the response

  • :snaky (Boolean) — default: true

    whether to convert response keys to snake_case

  • :token_method (Symbol) — default: :post_with_query_string
  • :headers (Hash)

    Additional request headers

Yields:

  • (req)

    The block is passed the request being made, allowing customization

Yield Parameters:

  • req (Faraday::Request)

    The request object that can be modified

Returns:

See Also:



257
258
259
260
261
262
263
264
265
# File 'lib/oauth2/client.rb', line 257

def revoke_token(token, token_type_hint = nil, params = {}, &block)
  params[:token_method] ||= :post_with_query_string
  req_opts = params_to_req_opts(params)
  req_opts[:params] ||= {}
  req_opts[:params][:token] = token
  req_opts[:params][:token_type_hint] = token_type_hint if token_type_hint

  request(http_method, revoke_url, req_opts, &block)
end

#revoke_url(params = nil) ⇒ String

The revoke endpoint URL of the OAuth2 provider

Parameters:

  • params (Hash, nil) (defaults to: nil)

    additional query parameters

Returns:

  • (String)

    the constructed revoke URL



119
120
121
# File 'lib/oauth2/client.rb', line 119

def revoke_url(params = nil)
  connection.build_url(options[:revoke_url], params).to_s
end

#token_url(params = nil) ⇒ String

The token endpoint URL of the OAuth2 provider

Parameters:

  • params (Hash, nil) (defaults to: nil)

    additional query parameters

Returns:

  • (String)

    the constructed token URL



111
112
113
# File 'lib/oauth2/client.rb', line 111

def token_url(params = nil)
  connection.build_url(options[:token_url], params).to_s
end