1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
|
# frozen_string_literal: true
module OAuth2
module Strategy
# The Authorization Code Strategy
#
# OAuth 2.1 notes:
# - PKCE is required for all OAuth clients using the authorization code flow (especially public clients).
# This library does not enforce PKCE generation/verification; implement PKCE in your application when required.
# - Redirect URIs must be compared using exact string matching by the Authorization Server.
# This client forwards redirect_uri but does not perform server-side validation.
#
# References:
# - OAuth 2.1 draft: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13
# - OAuth for native apps (RFC 8252) and PKCE (RFC 7636)
#
# @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.1
class AuthCode < Base
# The required query parameters for the authorize URL
#
# @param [Hash] params additional query parameters
def authorize_params(params = {})
params.merge("response_type" => "code", "client_id" => @client.id)
end
# The authorization URL endpoint of the provider
#
# @param [Hash] params additional query parameters for the URL
def authorize_url(params = {})
assert_valid_params(params)
@client.authorize_url(authorize_params.merge(params))
end
# Retrieve an access token given the specified validation code.
#
# @param [String] code The Authorization Code value
# @param [Hash] params additional params
# @param [Hash] opts access_token_opts, @see Client#get_token
# @note that you must also provide a :redirect_uri with most OAuth 2.0 providers
def get_token(code, params = {}, opts = {})
params = {"grant_type" => "authorization_code", "code" => code}.merge(@client.redirection_params).merge(params)
params_dup = params.dup
params.each_key do |key|
params_dup[key.to_s] = params_dup.delete(key) if key.is_a?(Symbol)
end
@client.get_token(params_dup, opts)
end
private
def assert_valid_params(params)
raise(ArgumentError, "client_secret is not allowed in authorize URL query params") if params.key?(:client_secret) || params.key?("client_secret")
end
end
end
end
|