class Google::Auth::WebUserAuthorizer
Varation on {Google::Auth::UserAuthorizer} adapted for Rack based web applications.
Example usage:
get('/') do user_id = request.session['user_email'] credentials = authorizer.get_credentials(user_id, request) if credentials.nil? redirect authorizer.get_authorization_url(user_id: user_id, request: request) end # Credentials are valid, can call APIs ... end get('/oauth2callback') do url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred( request) redirect url end
Instead of implementing the callback directly, applications are encouraged to use {Google::Auth::WebUserAuthorizer::CallbackApp} instead.
@see CallbackApp
@note Requires sessions are enabled
Constants
- AUTHORIZATION_ERROR
- AUTH_CODE_KEY
- CALLBACK_STATE_KEY
- CURRENT_URI_KEY
- ERROR_CODE_KEY
- INVALID_STATE_TOKEN_ERROR
- MISSING_AUTH_CODE_ERROR
- NIL_REQUEST_ERROR
- NIL_SESSION_ERROR
- SCOPE_KEY
- SESSION_ID_KEY
- STATE_PARAM
- XSRF_KEY
Attributes
Public Class Methods
# File lib/googleauth/web_user_authorizer.rb, line 205 def self.extract_callback_state request state = MultiJson.load(request.params[STATE_PARAM] || "{}") redirect_uri = state[CURRENT_URI_KEY] callback_state = { AUTH_CODE_KEY => request.params[AUTH_CODE_KEY], ERROR_CODE_KEY => request.params[ERROR_CODE_KEY], SESSION_ID_KEY => state[SESSION_ID_KEY], SCOPE_KEY => request.params[SCOPE_KEY] } [callback_state, redirect_uri] end
Handle the result of the oauth callback. This version defers the exchange of the code by temporarily stashing the results in the user’s session. This allows apps to use the generic {Google::Auth::WebUserAuthorizer::CallbackApp} handler for the callback without any additional customization.
Apps that wish to handle the callback directly should use {#handle_auth_callback} instead.
@param [Rack::Request] request
Current request
# File lib/googleauth/web_user_authorizer.rb, line 82 def self.handle_auth_callback_deferred request callback_state, redirect_uri = extract_callback_state request request.session[CALLBACK_STATE_KEY] = MultiJson.dump callback_state redirect_uri end
Initialize the authorizer
@param [Google::Auth::ClientID] client_id
Configured ID & secret for this application
@param [String, Array<String>] scope
Authorization scope to request
@param [Google::Auth::Stores::TokenStore] token_store
Backing storage for persisting user credentials
@param [String] legacy_callback_uri
URL (either absolute or relative) of the auth callback. Defaults to '/oauth2callback'. @deprecated This field is deprecated. Instead, use the keyword argument callback_uri.
@param [String] code_verifier
Random string of 43-128 chars used to verify the key exchange using PKCE.
Google::Auth::UserAuthorizer::new
# File lib/googleauth/web_user_authorizer.rb, line 104 def initialize client_id, scope, token_store, legacy_callback_uri = nil, callback_uri: nil, code_verifier: nil super client_id, scope, token_store, legacy_callback_uri, code_verifier: code_verifier, callback_uri: callback_uri end
Verifies the results of an authorization callback
@param [Hash] state
Callback state
@option state [String] AUTH_CODE_KEY
The authorization code
@option state [String] ERROR_CODE_KEY
Error message if failed
@param [Rack::Request] request
Current request
# File lib/googleauth/web_user_authorizer.rb, line 227 def self.validate_callback_state state, request raise Signet::AuthorizationError, MISSING_AUTH_CODE_ERROR if state[AUTH_CODE_KEY].nil? if state[ERROR_CODE_KEY] raise Signet::AuthorizationError, format(AUTHORIZATION_ERROR, state[ERROR_CODE_KEY]) elsif request.session[XSRF_KEY] != state[SESSION_ID_KEY] raise Signet::AuthorizationError, INVALID_STATE_TOKEN_ERROR end end
Public Instance Methods
Fetch stored credentials for the user from the given request session.
@param [String] user_id
Unique ID of the user for loading/storing credentials.
@param [Rack::Request] request
Current request. Optional. If omitted, this will attempt to fall back on the base class behavior of reading from the token store.
@param [Array<String>, String] scope
If specified, only returns credentials that have all the \ requested scopes
@return [Google::Auth::UserRefreshCredentials]
Stored credentials, nil if none present
@raise [Signet::AuthorizationError]
May raise an error if an authorization code is present in the session and exchange of the code fails
Google::Auth::UserAuthorizer#get_credentials
# File lib/googleauth/web_user_authorizer.rb, line 187 def get_credentials user_id, request = nil, scope = nil if request&.session&.key? CALLBACK_STATE_KEY # Note - in theory, no need to check required scope as this is # expected to be called immediately after a return from authorization state_json = request.session.delete CALLBACK_STATE_KEY callback_state = MultiJson.load state_json WebUserAuthorizer.validate_callback_state callback_state, request get_and_store_credentials_from_code( user_id: user_id, code: callback_state[AUTH_CODE_KEY], scope: callback_state[SCOPE_KEY], base_url: request.url ) else super user_id, scope end end
Handle the result of the oauth callback. Exchanges the authorization code from the request and persists to storage.
@param [String] user_id
Unique ID of the user for loading/storing credentials.
@param [Rack::Request] request
Current request
@return (Google::Auth::UserRefreshCredentials
, String)
credentials & next URL to redirect to
# File lib/googleauth/web_user_authorizer.rb, line 123 def handle_auth_callback user_id, request callback_state, redirect_uri = WebUserAuthorizer.extract_callback_state( request ) WebUserAuthorizer.validate_callback_state callback_state, request credentials = get_and_store_credentials_from_code( user_id: user_id, code: callback_state[AUTH_CODE_KEY], scope: callback_state[SCOPE_KEY], base_url: request.url ) [credentials, redirect_uri] end