Class: Rubino::OAuth::Provider::Google

Inherits:
Rubino::OAuth::Provider show all
Defined in:
lib/rubino/oauth/provider/google.rb

Overview

Google OAuth 2.0 / OpenID Connect provider.

Account info comes from the OIDC /v1/userinfo endpoint; sub is used as the stable account_id. The authorize request injects access_type=offline and prompt=consent — without both, Google only returns a refresh_token on the user’s very first consent and not on subsequent re-auths, which silently breaks token refresh.

Constant Summary collapse

USERINFO_URL =
"https://openidconnect.googleapis.com/v1/userinfo"
REVOKE_URL =
"https://oauth2.googleapis.com/revoke"

Instance Attribute Summary

Attributes inherited from Rubino::OAuth::Provider

#client_id, #client_secret, #metadata, #scopes

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Rubino::OAuth::Provider

#exchange_code, #id, #initialize, #refresh

Constructor Details

This class inherits a constructor from Rubino::OAuth::Provider

Class Method Details

.authorize_pathObject



20
# File 'lib/rubino/oauth/provider/google.rb', line 20

def self.authorize_path = "/o/oauth2/v2/auth"

.default_scopesObject



22
# File 'lib/rubino/oauth/provider/google.rb', line 22

def self.default_scopes = %w[openid email profile]

.display_nameObject



18
# File 'lib/rubino/oauth/provider/google.rb', line 18

def self.display_name  = "Google"

.idObject



17
# File 'lib/rubino/oauth/provider/google.rb', line 17

def self.id            = :google

.siteObject



19
# File 'lib/rubino/oauth/provider/google.rb', line 19

def self.site          = "https://accounts.google.com"

.token_pathObject



21
# File 'lib/rubino/oauth/provider/google.rb', line 21

def self.token_path = "https://oauth2.googleapis.com/token"

Instance Method Details

#build_authorize_request(redirect_uri:, scopes: nil, extra: {}) ⇒ Object



52
53
54
55
# File 'lib/rubino/oauth/provider/google.rb', line 52

def build_authorize_request(redirect_uri:, scopes: nil, extra: {})
  super(redirect_uri: redirect_uri, scopes: scopes,
        extra: { access_type: "offline", prompt: "consent" }.merge(extra))
end

#fetch_account_info(access_token) ⇒ Object



41
42
43
44
45
46
47
48
49
50
# File 'lib/rubino/oauth/provider/google.rb', line 41

def (access_token)
  response = Faraday.get(USERINFO_URL, nil, "Authorization" => "Bearer #{access_token}")
  user = JSON.parse(response.body)

  {
    account_id: user["sub"],
    account_email: user["email"],
    metadata: { name: user["name"], picture: user["picture"], hd: user["hd"] }
  }
end

#revoke(token) ⇒ Boolean

Revoke an access or refresh token. Google’s revoke endpoint accepts either; revoking a refresh token implicitly invalidates all access tokens derived from it, so callers should pass the refresh token when available. developers.google.com/identity/protocols/oauth2/web-server#tokenrevoke

Parameters:

  • token (String)

    access or refresh token

Returns:

  • (Boolean)

    true on 200, false otherwise.



35
36
37
38
39
# File 'lib/rubino/oauth/provider/google.rb', line 35

def revoke(token)
  response = Faraday.post(REVOKE_URL, { token: token },
                          "Content-Type" => "application/x-www-form-urlencoded")
  response.success?
end