class OmniAuth::Strategies::OAuth2

Authentication strategy for connecting with APIs constructed using the [OAuth 2.0 Specification](tools.ietf.org/html/draft-ietf-oauth-v2-10). You must generally register your application with the provider and utilize an application id and secret in order to authenticate using OAuth 2.0.

Attributes

access_token[RW]

Public Class Methods

inherited(subclass) click to toggle source
# File lib/omniauth/strategies/oauth2.rb, line 17
def self.inherited(subclass)
  OmniAuth::Strategy.included(subclass)
end

Public Instance Methods

authorize_params() click to toggle source
# File lib/omniauth/strategies/oauth2.rb, line 62
def authorize_params # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  options.authorize_params[:state] = SecureRandom.hex(24)

  if OmniAuth.config.test_mode
    @env ||= {}
    @env["rack.session"] ||= {}
  end

  params = options.authorize_params
                  .merge(options_for("authorize"))
                  .merge(pkce_authorize_params)

  session["omniauth.pkce.verifier"] = options.pkce_verifier if options.pkce
  session["omniauth.state"] = params[:state]

  params
end
callback_phase() click to toggle source
Calls superclass method
# File lib/omniauth/strategies/oauth2.rb, line 84
def callback_phase # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
  error = request.params["error_reason"] || request.params["error"]
  if !options.provider_ignores_state && (request.params["state"].to_s.empty? || request.params["state"] != session.delete("omniauth.state"))
    fail!(:csrf_detected, CallbackError.new(:csrf_detected, "CSRF detected"))
  elsif error
    fail!(error, CallbackError.new(request.params["error"], request.params["error_description"] || request.params["error_reason"], request.params["error_uri"]))
  else
    self.access_token = build_access_token
    self.access_token = access_token.refresh! if access_token.expired?
    super
  end
rescue ::OAuth2::Error, CallbackError => e
  fail!(:invalid_credentials, e)
rescue ::Timeout::Error, ::Errno::ETIMEDOUT => e
  fail!(:timeout, e)
rescue ::SocketError => e
  fail!(:failed_to_connect, e)
end
client() click to toggle source
# File lib/omniauth/strategies/oauth2.rb, line 46
def client
  ::OAuth2::Client.new(options.client_id, options.client_secret, deep_symbolize(options.client_options))
end
request_phase() click to toggle source
# File lib/omniauth/strategies/oauth2.rb, line 58
def request_phase
  redirect client.auth_code.authorize_url({:redirect_uri => callback_url}.merge(authorize_params))
end
token_params() click to toggle source
# File lib/omniauth/strategies/oauth2.rb, line 80
def token_params
  options.token_params.merge(options_for("token")).merge(pkce_token_params)
end

Protected Instance Methods

build_access_token() click to toggle source
# File lib/omniauth/strategies/oauth2.rb, line 124
def build_access_token
  verifier = request.params["code"]
  client.auth_code.get_token(verifier, {:redirect_uri => callback_url}.merge(token_params.to_hash(:symbolize_keys => true)), deep_symbolize(options.auth_token_params))
end
deep_symbolize(options) click to toggle source
# File lib/omniauth/strategies/oauth2.rb, line 129
def deep_symbolize(options)
  options.each_with_object({}) do |(key, value), hash|
    hash[key.to_sym] = value.is_a?(Hash) ? deep_symbolize(value) : value
  end
end
options_for(option) click to toggle source
# File lib/omniauth/strategies/oauth2.rb, line 135
def options_for(option)
  hash = {}
  options.send(:"#{option}_options").select { |key| options[key] }.each do |key|
    hash[key.to_sym] = if options[key].respond_to?(:call)
                         options[key].call(env)
                       else
                         options[key]
                       end
  end
  hash
end
pkce_authorize_params() click to toggle source
# File lib/omniauth/strategies/oauth2.rb, line 105
def pkce_authorize_params
  return {} unless options.pkce

  options.pkce_verifier = SecureRandom.hex(64)

  # NOTE: see https://tools.ietf.org/html/rfc7636#appendix-A
  {
    :code_challenge => options.pkce_options[:code_challenge]
                              .call(options.pkce_verifier),
    :code_challenge_method => options.pkce_options[:code_challenge_method],
  }
end
pkce_token_params() click to toggle source
# File lib/omniauth/strategies/oauth2.rb, line 118
def pkce_token_params
  return {} unless options.pkce

  {:code_verifier => session.delete("omniauth.pkce.verifier")}
end