class Google::Auth::WebUserAuthorizer

@note Requires sessions are enabled
@see CallbackApp
encouraged to use {Google::Auth::WebUserAuthorizer::CallbackApp} instead.
Instead of implementing the callback directly, applications are
end
redirect url
request)
url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(
get(‘/oauth2callback’) do
end

# Credentials are valid, can call APIs
end
request: request)
redirect authorizer.get_authorization_url(user_id: user_id,
if credentials.nil?
credentials = authorizer.get_credentials(user_id, request)
user_id = request.session[‘user_email’]
get(‘/’) do
Example usage:
web applications.
Varation on {Google::Auth::UserAuthorizer} adapted for Rack based

def self.extract_callback_state request

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

def self.handle_auth_callback_deferred request

Parameters:
  • request (Rack::Request) --
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

def self.validate_callback_state state, request

Parameters:
  • request (Rack::Request) --
  • state (Hash) --

Options Hash: (**state)
  • ERROR_CODE_KEY (String) --
  • AUTH_CODE_KEY (String) --
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

def get_authorization_url options = {}

Returns:
  • (String) -

Parameters:
  • state (Hash) --
  • scope (String, Array) --
  • redirect_to (String) --
  • request (Rack::Request) --
  • login_hint (String) --
def get_authorization_url options = {}
  options = options.dup
  request = options[:request]
  raise NIL_REQUEST_ERROR if request.nil?
  raise NIL_SESSION_ERROR if request.session.nil?
  state = options[:state] || {}
  redirect_to = options[:redirect_to] || request.url
  request.session[XSRF_KEY] = SecureRandom.base64
  options[:state] = MultiJson.dump(state.merge(
                                     SESSION_ID_KEY  => request.session[XSRF_KEY],
                                     CURRENT_URI_KEY => redirect_to
                                   ))
  options[:base_url] = request.url
  super options
end

def get_credentials user_id, request = nil, scope = nil

Raises:
  • (Signet::AuthorizationError) -

Returns:
  • (Google::Auth::UserRefreshCredentials) -

Parameters:
  • scope (Array, String) --
  • request (Rack::Request) --
  • user_id (String) --
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

def handle_auth_callback user_id, request

Returns:
  • (Google::Auth::UserRefreshCredentials, String) -

Parameters:
  • request (Rack::Request) --
  • user_id (String) --
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

def initialize client_id, scope, token_store, callback_uri = nil

Parameters:
  • callback_uri (String) --
  • token_store (Google::Auth::Stores::TokenStore) --
  • scope (String, Array) --
  • client_id (Google::Auth::ClientID) --
def initialize client_id, scope, token_store, callback_uri = nil
  super client_id, scope, token_store, callback_uri
end