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::Web::AuthCallbackApp} instead.
For rails apps, see {Google::Auth::ControllerHelpers}
@see {Google::Auth::AuthCallbackApp} @see {Google::Auth::ControllerHelpers} @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 207 def self.extract_callback_state(request) state = MultiJson.load(request[STATE_PARAM] || '{}') redirect_uri = state[CURRENT_URI_KEY] callback_state = { AUTH_CODE_KEY => request[AUTH_CODE_KEY], ERROR_CODE_KEY => request[ERROR_CODE_KEY], SESSION_ID_KEY => state[SESSION_ID_KEY], SCOPE_KEY => request[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 100 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] callback_uri
URL (either absolute or relative) of the auth callback. Defaults to '/oauth2callback'
# File lib/googleauth/web_user_authorizer.rb, line 117 def initialize(client_id, scope, token_store, callback_uri = nil) super(client_id, scope, token_store, 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 229 def self.validate_callback_state(state, request) if state[AUTH_CODE_KEY].nil? raise Signet::AuthorizationError, MISSING_AUTH_CODE_ERROR elsif state[ERROR_CODE_KEY] raise Signet::AuthorizationError, sprintf(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.
@param [String] user_id
Unique ID of the user for loading/storing credentials.
@param [Rack::Request] request
Current request
@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
# File lib/googleauth/web_user_authorizer.rb, line 189 def get_credentials(user_id, request, 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 130 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