Module: BetterAuth::OAuth2
- Defined in:
- lib/better_auth/oauth2.rb
Class Method Summary collapse
- .create_refresh_access_token_request(refresh_token:, options:, authentication: nil, extra_params: nil, resource: nil) ⇒ Object
- .post_form(token_endpoint, request) ⇒ Object
- .refresh_access_token(refresh_token:, token_endpoint:, options:, authentication: nil, extra_params: nil, resource: nil, fetcher: nil) ⇒ Object
- .stringify_keys(hash) ⇒ Object
- .validate_token(token, jwks:, audience: nil, issuer: nil) ⇒ Object
Class Method Details
.create_refresh_access_token_request(refresh_token:, options:, authentication: nil, extra_params: nil, resource: nil) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/better_auth/oauth2.rb', line 58 def create_refresh_access_token_request(refresh_token:, options:, authentication: nil, extra_params: nil, resource: nil) body = { "grant_type" => "refresh_token", "refresh_token" => refresh_token } headers = { "content-type" => "application/x-www-form-urlencoded", "accept" => "application/json" } client_id = Array([:client_id] || ["client_id"] || [:clientId] || ["clientId"]).first client_secret = [:client_secret] || ["client_secret"] || [:clientSecret] || ["clientSecret"] if authentication.to_s == "basic" headers["authorization"] = "Basic #{Base64.strict_encode64("#{client_id}:#{client_secret}")}" else body["client_id"] = client_id if client_id body["client_secret"] = client_secret if client_secret end Array(resource).each { |entry| (body["resource"] ||= []) << entry } if resource extra_params&.each { |key, value| body[key.to_s] = value } {body: body, headers: headers} end |
.post_form(token_endpoint, request) ⇒ Object
82 83 84 85 86 |
# File 'lib/better_auth/oauth2.rb', line 82 def post_form(token_endpoint, request) uri = URI.parse(token_endpoint) response = Net::HTTP.post(uri, URI.encode_www_form(request[:body]), request[:headers]) JSON.parse(response.body) end |
.refresh_access_token(refresh_token:, token_endpoint:, options:, authentication: nil, extra_params: nil, resource: nil, fetcher: nil) ⇒ Object
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 |
# File 'lib/better_auth/oauth2.rb', line 32 def refresh_access_token(refresh_token:, token_endpoint:, options:, authentication: nil, extra_params: nil, resource: nil, fetcher: nil) request = create_refresh_access_token_request( refresh_token: refresh_token, options: , authentication: authentication, extra_params: extra_params, resource: resource ) data = fetcher ? fetcher.call(token_endpoint, request) : post_form(token_endpoint, request) now = Time.now tokens = { access_token: data["access_token"] || data[:access_token], refresh_token: data["refresh_token"] || data[:refresh_token], token_type: data["token_type"] || data[:token_type], scopes: (data["scope"] || data[:scope])&.split(" "), id_token: data["id_token"] || data[:id_token] }.compact expires_in = data["expires_in"] || data[:expires_in] tokens[:access_token_expires_at] = now + expires_in.to_i if expires_in refresh_expires_in = data["refresh_token_expires_in"] || data[:refresh_token_expires_in] tokens[:refresh_token_expires_at] = now + refresh_expires_in.to_i if refresh_expires_in tokens end |
.stringify_keys(hash) ⇒ Object
88 89 90 91 92 |
# File 'lib/better_auth/oauth2.rb', line 88 def stringify_keys(hash) hash.each_with_object({}) do |(key, value), result| result[key.to_s] = value.is_a?(Hash) ? stringify_keys(value) : value end end |
.validate_token(token, jwks:, audience: nil, issuer: nil) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/better_auth/oauth2.rb', line 12 def validate_token(token, jwks:, audience: nil, issuer: nil) header = JWT.decode(token, nil, false).last kid = header["kid"] raise APIError.new("UNAUTHORIZED", message: "Missing jwt kid") if kid.to_s.empty? key_data = Array(jwks["keys"] || jwks[:keys]).find { |key| (key["kid"] || key[:kid]).to_s == kid.to_s } raise APIError.new("UNAUTHORIZED", message: "kid doesn't match any key") unless key_data public_key = JWT::JWK.import(stringify_keys(key_data)).public_key algorithm = header["alg"] || key_data["alg"] || key_data[:alg] = {algorithm: algorithm} [:aud] = audience if audience [:verify_aud] = true if audience [:iss] = issuer if issuer [:verify_iss] = true if issuer JWT.decode(token, public_key, true, **).first rescue JWT::DecodeError => error raise APIError.new("UNAUTHORIZED", message: error.) end |