class Google::Auth::UserAuthorizer
Handles an interactive 3-Legged-OAuth2 (3LO) user consent authorization.
Example usage for a simple command line app:
credentials = authorizer.get_credentials(user_id) if credentials.nil? url = authorizer.get_authorization_url( base_url: OOB_URI) puts "Open the following URL in the browser and enter the " + "resulting code after authorization" puts url code = gets credentials = authorizer.get_and_store_credentials_from_code( user_id: user_id, code: code, base_url: OOB_URI) end # Credentials ready to use, call APIs ...
Constants
- MISMATCHED_CLIENT_ID_ERROR
- MISSING_ABSOLUTE_URL_ERROR
- NIL_CLIENT_ID_ERROR
- NIL_SCOPE_ERROR
- NIL_TOKEN_STORE_ERROR
- NIL_USER_ID_ERROR
Public Class Methods
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/user_authorizer.rb, line 60 def initialize client_id, scope, token_store, callback_uri = nil raise NIL_CLIENT_ID_ERROR if client_id.nil? raise NIL_SCOPE_ERROR if scope.nil? @client_id = client_id @scope = Array(scope) @token_store = token_store @callback_uri = callback_uri || "/oauth2callback" end
Public Instance Methods
Exchanges an authorization code returned in the oauth callback. Additionally, stores the resulting credentials in the token store if the exchange is successful.
@param [String] user_id
Unique ID of the user for loading/storing credentials.
@param [String] code
The authorization code from the OAuth callback
@param [String, Array<String>] scope
Authorization scope requested. Overrides the instance scopes if not nil.
@param [String] base_url
Absolute URL to resolve the configured callback uri against. Required if the configured callback uri is a relative.
@return [Google::Auth::UserRefreshCredentials]
Credentials if exchange is successful
# File lib/googleauth/user_authorizer.rb, line 182 def get_and_store_credentials_from_code options = {} credentials = get_credentials_from_code options store_credentials options[:user_id], credentials end
Fetch stored credentials for the user.
@param [String] user_id
Unique ID of the user for loading/storing credentials.
@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
# File lib/googleauth/user_authorizer.rb, line 111 def get_credentials user_id, scope = nil saved_token = stored_token user_id return nil if saved_token.nil? data = MultiJson.load saved_token if data.fetch("client_id", @client_id.id) != @client_id.id raise format(MISMATCHED_CLIENT_ID_ERROR, data["client_id"], @client_id.id) end credentials = UserRefreshCredentials.new( client_id: @client_id.id, client_secret: @client_id.secret, scope: data["scope"] || @scope, access_token: data["access_token"], refresh_token: data["refresh_token"], expires_at: data.fetch("expiration_time_millis", 0) / 1000 ) scope ||= @scope return monitor_credentials user_id, credentials if credentials.includes_scope? scope nil end
Exchanges an authorization code returned in the oauth callback
@param [String] user_id
Unique ID of the user for loading/storing credentials.
@param [String] code
The authorization code from the OAuth callback
@param [String, Array<String>] scope
Authorization scope requested. Overrides the instance scopes if not nil.
@param [String] base_url
Absolute URL to resolve the configured callback uri against. Required if the configured callback uri is a relative.
@return [Google::Auth::UserRefreshCredentials]
Credentials if exchange is successful
# File lib/googleauth/user_authorizer.rb, line 149 def get_credentials_from_code options = {} user_id = options[:user_id] code = options[:code] scope = options[:scope] || @scope base_url = options[:base_url] credentials = UserRefreshCredentials.new( client_id: @client_id.id, client_secret: @client_id.secret, redirect_uri: redirect_uri_for(base_url), scope: scope ) credentials.code = code credentials.fetch_access_token!({}) monitor_credentials user_id, credentials end
Store credentials for a user. Generally not required to be called directly, but may be used to migrate tokens from one store to another.
@param [String] user_id
Unique ID of the user for loading/storing credentials.
@param [Google::Auth::UserRefreshCredentials] credentials
Credentials to store.
# File lib/googleauth/user_authorizer.rb, line 212 def store_credentials user_id, credentials json = MultiJson.dump( client_id: credentials.client_id, access_token: credentials.access_token, refresh_token: credentials.refresh_token, scope: credentials.scope, expiration_time_millis: credentials.expires_at.to_i * 1000 ) @token_store.store user_id, json credentials end
Private Instance Methods
Begin watching a credential for refreshes so the access token can be saved.
@param [String] user_id
Unique ID of the user for loading/storing credentials.
@param [Google::Auth::UserRefreshCredentials] credentials
Credentials to store.
# File lib/googleauth/user_authorizer.rb, line 245 def monitor_credentials user_id, credentials credentials.on_refresh do |cred| store_credentials user_id, cred end credentials end
Resolve the redirect uri against a base.
@param [String] base_url
Absolute URL to resolve the callback against if necessary.
@return [String]
Redirect URI
# File lib/googleauth/user_authorizer.rb, line 258 def redirect_uri_for base_url return @callback_uri if uri_is_postmessage?(@callback_uri) || !URI(@callback_uri).scheme.nil? raise format(MISSING_ABSOLUTE_URL_ERROR, @callback_uri) if base_url.nil? || URI(base_url).scheme.nil? URI.join(base_url, @callback_uri).to_s end
@private Fetch stored token with given user_id
@param [String] user_id
Unique ID of the user for loading/storing credentials.
@return [String] The saved token from @token_store
# File lib/googleauth/user_authorizer.rb, line 231 def stored_token user_id raise NIL_USER_ID_ERROR if user_id.nil? raise NIL_TOKEN_STORE_ERROR if @token_store.nil? @token_store.load user_id end
Check if URI is Google's postmessage flow (not a valid redirect_uri by spec, but allowed)
# File lib/googleauth/user_authorizer.rb, line 265 def uri_is_postmessage? uri uri.to_s.casecmp("postmessage").zero? end