概要
OAuth ベースの Google ログイン スムーズ リンクは、OAuth リンクの上層に Google ログインを追加します。これにより、Google ユーザーはシームレスにリンクできます。また、アカウント作成も有効になり、ユーザーは Google アカウントを使用してサービスに新しいアカウントを作成できます。
OAuth と Google ログインを使用してアカウント リンクを行うには、次の一般的な手順に従います。
- まず、ユーザーの Google プロフィールにアクセスすることについてユーザーに同意を求めます。
- プロフィールの情報を使用して、ユーザー アカウントが存在するかどうかを確認します。
- 既存のユーザーの場合は、アカウントをリンクします。
- 認証システムで Google ユーザーに一致するユーザーが見つからない場合は、Google から受け取った ID トークンを検証します。その後、ID トークンに含まれているプロフィール情報に基づいてユーザー アカウントを作成できます。

図 1. 簡素化されたリンクを使用したユーザーのスマートフォンでのアカウント リンク
簡素化されたリンクの要件
- 基本的なウェブ OAuth リンクフローを実装します。サービスは、OAuth 2.0 準拠の認可エンドポイントとトークン交換エンドポイントをサポートする必要があります。
- トークン交換エンドポイントは、JSON Web Token(JWT)アサーションをサポートし、
check
、create
、get
インテントを実装する必要があります。
OAuth サーバーを実装する
トークン交換エンドポイントは、check
、create
、get
インテントをサポートする必要があります。以下の図は、アカウントのリンクフローで完了する手順と、さまざまなインテントの呼び出しタイミングを示しています。
- ユーザーは認証システムにアカウントを持っていますか?(ユーザーが [はい] または [いいえ] を選択して決定)
- はい : ユーザーは Google アカウントに関連付けられているメールアドレスを使用してプラットフォームにログインしていますか?(ユーザーが [はい] または [いいえ] を選択して決定)
- はい : ユーザーの認証システムに一致するアカウントがありますか?(確認のために
check intent
が呼び出されます)- YES :
get intent
が呼び出され、get intent が正常に返された場合はアカウントがリンクされます。 - 「いいえ」の場合 : 新しいアカウントを作成しますか?(ユーザーが [はい] または [いいえ] を選択して決定)
- YES :
create intent
が呼び出され、作成インテントの戻り値が成功した場合はアカウントがリンクされます。 - いいえ : ウェブ OAuth フローがトリガーされ、ユーザーはブラウザにリダイレクトされ、別のメールアドレスでリンクするオプションが表示されます。
- YES :
- YES :
- いいえ : ウェブ OAuth フローがトリガーされ、ユーザーはブラウザにリダイレクトされ、別のメールアドレスにリンクするオプションが表示されます。
- はい : ユーザーの認証システムに一致するアカウントがありますか?(確認のために
- 「いいえ」の場合 : ユーザーの認証システムに一致するアカウントがありますか?(確認のために
check intent
が呼び出されます)- YES :
get intent
が呼び出され、get intent が正常に返された場合はアカウントがリンクされます。 - いいえ :
create intent
が呼び出され、作成インテントの戻り値が正常であればアカウントがリンクされます。
- YES :
- はい : ユーザーは Google アカウントに関連付けられているメールアドレスを使用してプラットフォームにログインしていますか?(ユーザーが [はい] または [いいえ] を選択して決定)
既存のユーザー アカウントを確認する(インテントを確認する)
ユーザーが Google プロフィールへのアクセスに同意すると、 Google ユーザーの ID に関する署名付きアサーションを含むリクエスト。「 アサーションには、ユーザーの Google アカウント ID、 表示されます。アプリケーション用に構成されたトークン交換エンドポイント プロジェクトがリクエストを処理できます
対応する Google アカウントが認証にすでに存在する場合
トークン交換エンドポイントは account_found=true
を返します。もし
Google アカウントが既存のユーザーと一致しません。トークン交換エンドポイントがあります
account_found=false
で HTTP 404 Not Found エラーを返す。
リクエストは次のようになります。
POST /token HTTP/1.1 Host: oauth2.example.com Content-Type: application/x-www-form-urlencoded grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&intent=check&assertion=JWT&scope=SCOPES&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET
トークン交換エンドポイントでは、以下のパラメータを処理する必要があります。
トークン交換エンドポイントのパラメータ | |
---|---|
intent |
これらのリクエストでは、このパラメータの値は
check 。 |
grant_type |
交換されるトークンの種類。これらのリクエストでは、
パラメータの値は urn:ietf:params:oauth:grant-type:jwt-bearer です。 |
assertion |
Google ユーザー ID の署名付きアサーションを提供する JSON Web Token(JWT)。この JWT には、ユーザーの認証情報、 Google アカウント ID、名前、メールアドレス。 |
client_id |
Google に割り当てたクライアント ID。 |
client_secret |
Google に割り当てたクライアント シークレット。 |
check
インテント リクエストに応答するには、トークン交換エンドポイントで次の手順を行う必要があります。
- JWT アサーションを検証してデコードします。
- Google アカウントが認証システムにすでに存在するかどうかを確認します。
Validate and decode the JWT assertion
You can validate and decode the JWT assertion by using a JWT-decoding library for your language. Use Google's public keys, available in JWK or PEM formats, to verify the token's signature.
When decoded, the JWT assertion looks like the following example:
{ "sub": "1234567890", // The unique ID of the user's Google Account "iss": "https://accounts.google.com", // The assertion's issuer "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID "iat": 233366400, // Unix timestamp of the assertion's creation time "exp": 233370000, // Unix timestamp of the assertion's expiration time "name": "Jan Jansen", "given_name": "Jan", "family_name": "Jansen", "email": "jan@gmail.com", // If present, the user's email address "email_verified": true, // true, if Google has verified the email address "hd": "example.com", // If present, the host domain of the user's GSuite email address // If present, a URL to user's profile picture "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ", "locale": "en_US" // User's locale, from browser or phone settings }
In addition to verifying the token's signature, verify that the assertion's
issuer (iss
field) is https://accounts.google.com
, that the audience
(aud
field) is your assigned client ID, and that the token has not expired
(exp
field).
Using the email
, email_verified
and hd
fields you can determine if
Google hosts and is authoritative for an email address. In cases where Google is
authoritative the user is currently known to be the legitimate account owner
and you may skip password or other challenges methods. Otherwise, these methods
can be used to verify the account prior to linking.
Cases where Google is authoritative:
email
has a@gmail.com
suffix, this is a Gmail account.email_verified
is true andhd
is set, this is a G Suite account.
Users may register for Google Accounts without using Gmail or G Suite. When
email
does not contain a @gmail.com
suffix and hd
is absent Google is not
authoritative and password or other challenge methods are recommended to verify
the user. email_verified
can also be true as Google initially verified the
user when the Google account was created, however ownership of the third party
email account may have since changed.
Google アカウントが認証システムに存在するかどうかの確認
次のいずれかの条件を満たしていることを確認します。
- アサーションの
sub
フィールドにある Google アカウント ID がユーザーのものである データベースです - アサーションに含まれているメールアドレスが、ユーザーのデータベースに登録されているユーザーと一致している。
いずれかの条件が true の場合、ユーザーは登録済みです。その場合、 次のようなレスポンスが返されます。
HTTP/1.1 200 Success Content-Type: application/json;charset=UTF-8 { "account_found":"true", }
Google アカウント ID もメールアドレスも
アサーションがデータベース内のユーザーと一致した場合、ユーザーはまだ登録されていません。イン
この場合、トークン交換エンドポイントは HTTP 404 エラーを返す必要があります。
"account_found": "false"
を指定します。次に例を示します。
HTTP/1.1 404 Not found Content-Type: application/json;charset=UTF-8 { "account_found":"false", }
Handle automatic linking (get intent)
After the user gives consent to access their Google profile, Google sends a request that contains a signed assertion of the Google user's identity. The assertion contains information that includes the user's Google Account ID, name, and email address. The token exchange endpoint configured for your project handles that request.
If the corresponding Google Account is already present in your authentication
system, your token exchange endpoint returns a token for the user. If the
Google Account doesn't match an existing user, your token exchange endpoint
returns a linking_error
error and optional login_hint
.
The request has the following form:
POST /token HTTP/1.1 Host: oauth2.example.com Content-Type: application/x-www-form-urlencoded grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&intent=get&assertion=JWT&scope=SCOPES&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET
Your token exchange endpoint must be able to handle the following parameters:
Token endpoint parameters | |
---|---|
intent |
For these requests, the value of this parameter is get . |
grant_type |
The type of token being exchanged. For these requests, this
parameter has the value urn:ietf:params:oauth:grant-type:jwt-bearer . |
assertion |
A JSON Web Token (JWT) that provides a signed assertion of the Google user's identity. The JWT contains information that includes the user's Google Account ID, name, and email address. |
scope |
Optional: Any scopes that you've configured Google to request from users. |
client_id |
The client ID you assigned to Google. |
client_secret |
The client secret you assigned to Google. |
To respond to the get
intent requests, your token exchange endpoint must perform the following steps:
- Validate and decode the JWT assertion.
- Check if the Google account is already present in your authentication system.
Validate and decode the JWT assertion
You can validate and decode the JWT assertion by using a JWT-decoding library for your language. Use Google's public keys, available in JWK or PEM formats, to verify the token's signature.
When decoded, the JWT assertion looks like the following example:
{ "sub": "1234567890", // The unique ID of the user's Google Account "iss": "https://accounts.google.com", // The assertion's issuer "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID "iat": 233366400, // Unix timestamp of the assertion's creation time "exp": 233370000, // Unix timestamp of the assertion's expiration time "name": "Jan Jansen", "given_name": "Jan", "family_name": "Jansen", "email": "jan@gmail.com", // If present, the user's email address "email_verified": true, // true, if Google has verified the email address "hd": "example.com", // If present, the host domain of the user's GSuite email address // If present, a URL to user's profile picture "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ", "locale": "en_US" // User's locale, from browser or phone settings }
In addition to verifying the token's signature, verify that the assertion's
issuer (iss
field) is https://accounts.google.com
, that the audience
(aud
field) is your assigned client ID, and that the token has not expired
(exp
field).
Using the email
, email_verified
and hd
fields you can determine if
Google hosts and is authoritative for an email address. In cases where Google is
authoritative the user is currently known to be the legitimate account owner
and you may skip password or other challenges methods. Otherwise, these methods
can be used to verify the account prior to linking.
Cases where Google is authoritative:
email
has a@gmail.com
suffix, this is a Gmail account.email_verified
is true andhd
is set, this is a G Suite account.
Users may register for Google Accounts without using Gmail or G Suite. When
email
does not contain a @gmail.com
suffix and hd
is absent Google is not
authoritative and password or other challenge methods are recommended to verify
the user. email_verified
can also be true as Google initially verified the
user when the Google account was created, however ownership of the third party
email account may have since changed.
Check if the Google account is already present in your authentication system
Check whether either of the following conditions are true:
- The Google Account ID, found in the assertion's
sub
field, is in your user database. - The email address in the assertion matches a user in your user database.
If an account is found for the user, issue an access token and return the values in a JSON object in the body of your HTTPS response, like in the following example:
{ "token_type": "Bearer", "access_token": "ACCESS_TOKEN", "expires_in": SECONDS_TO_EXPIRATION }
In some cases, account linking based on ID token might fail for the user. If it
does so for any reason, your token exchange endpoint needs to reply with a HTTP
401 error that specifies error=linking_error
, as the following example shows:
HTTP/1.1 401 Unauthorized Content-Type: application/json;charset=UTF-8 { "error":"linking_error", "login_hint":"foo@bar.com" }
When Google receives a 401 error response with linking_error
, Google sends
the user to your authorization endpoint with login_hint
as a parameter. The
user completes account linking using the OAuth linking flow in their browser.
Handle account creation via Google Sign-In (create intent)
When a user needs to create an account on your service, Google makes a request
to your token exchange endpoint that specifies intent=create
.
The request has the following form:
POST /token HTTP/1.1 Host: oauth2.example.com Content-Type: application/x-www-form-urlencoded response_type=token&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&scope=SCOPES&intent=create&assertion=JWT&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET
Your token exchange endpoint must able to handle the following parameters:
Token endpoint parameters | |
---|---|
intent |
For these requests, the value of this parameter is create . |
grant_type |
The type of token being exchanged. For these requests, this
parameter has the value urn:ietf:params:oauth:grant-type:jwt-bearer . |
assertion |
A JSON Web Token (JWT) that provides a signed assertion of the Google user's identity. The JWT contains information that includes the user's Google Account ID, name, and email address. |
client_id |
The client ID you assigned to Google. |
client_secret |
The client secret you assigned to Google. |
The JWT within the assertion
parameter contains the user's Google Account ID,
name, and email address, which you can use to create a new account on your
service.
To respond to the create
intent requests, your token exchange endpoint must perform the following steps:
- Validate and decode the JWT assertion.
- Validate user information and create new account.
Validate and decode the JWT assertion
You can validate and decode the JWT assertion by using a JWT-decoding library for your language. Use Google's public keys, available in JWK or PEM formats, to verify the token's signature.
When decoded, the JWT assertion looks like the following example:
{ "sub": "1234567890", // The unique ID of the user's Google Account "iss": "https://accounts.google.com", // The assertion's issuer "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID "iat": 233366400, // Unix timestamp of the assertion's creation time "exp": 233370000, // Unix timestamp of the assertion's expiration time "name": "Jan Jansen", "given_name": "Jan", "family_name": "Jansen", "email": "jan@gmail.com", // If present, the user's email address "email_verified": true, // true, if Google has verified the email address "hd": "example.com", // If present, the host domain of the user's GSuite email address // If present, a URL to user's profile picture "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ", "locale": "en_US" // User's locale, from browser or phone settings }
In addition to verifying the token's signature, verify that the assertion's
issuer (iss
field) is https://accounts.google.com
, that the audience
(aud
field) is your assigned client ID, and that the token has not expired
(exp
field).
Using the email
, email_verified
and hd
fields you can determine if
Google hosts and is authoritative for an email address. In cases where Google is
authoritative the user is currently known to be the legitimate account owner
and you may skip password or other challenges methods. Otherwise, these methods
can be used to verify the account prior to linking.
Cases where Google is authoritative:
email
has a@gmail.com
suffix, this is a Gmail account.email_verified
is true andhd
is set, this is a G Suite account.
Users may register for Google Accounts without using Gmail or G Suite. When
email
does not contain a @gmail.com
suffix and hd
is absent Google is not
authoritative and password or other challenge methods are recommended to verify
the user. email_verified
can also be true as Google initially verified the
user when the Google account was created, however ownership of the third party
email account may have since changed.
Validate user information and create new account
Check whether either of the following conditions are true:
- The Google Account ID, found in the assertion's
sub
field, is in your user database. - The email address in the assertion matches a user in your user database.
If either condition is true, prompt the user to link their existing account
with their Google Account. To do so, respond to the request with an HTTP 401 error
that specifies error=linking_error
and gives the user's email address as the
login_hint
. The following is a sample response:
HTTP/1.1 401 Unauthorized Content-Type: application/json;charset=UTF-8 { "error":"linking_error", "login_hint":"foo@bar.com" }
When Google receives a 401 error response with linking_error
, Google sends
the user to your authorization endpoint with login_hint
as a parameter. The
user completes account linking using the OAuth linking flow in their browser.
If neither condition is true, create a new user account with the information provided in the JWT. New accounts don't typically have a password set. It's recommended that you add Google Sign-In to other platforms to enable users to log in with Google across the surfaces of your application. Alternatively, you can email the user a link that starts your password recovery flow to allow the user to set a password to sign in on other platforms.
When the creation is completed, issue an access token and return the values in a JSON object in the body of your HTTPS response, like in the following example:
{ "token_type": "Bearer", "access_token": "ACCESS_TOKEN", "expires_in": SECONDS_TO_EXPIRATION }
Google API クライアント ID を取得する
アカウント リンクの登録プロセスで、Google API クライアント ID を指定する必要があります。
OAuth のリンクの手順で作成したプロジェクトを使用して API クライアント ID を取得します。そのための手順は次のとおりです。
- Go to the Credentials page.
Google API プロジェクトを作成または選択します。
プロジェクトにウェブ アプリケーション タイプのクライアント ID がない場合は、[クライアントを作成] をクリックして作成します。[承認済みの JavaScript 生成元] ボックスに、サイトのドメインを含めてください。ローカルテストまたは開発を行う場合は、[Authorized JavaScript origins] フィールドに
http://localhost
とhttp://localhost:<port_number>
の両方を追加する必要があります。
実装の検証
実装を検証するには、OAuth 2.0 Playground ツールを使用します。
ツールで、次の操作を行います。
- [Configuration] をクリックして [OAuth 2.0 Configuration] ウィンドウを開きます。
- [OAuth flow] フィールドで、[Client-side] を選択します。
- [OAuth Endpoints](OAuth エンドポイント)で、[Custom](カスタム)を選択します。
- 対応するフィールドに、OAuth 2.0 エンドポイントと Google に割り当てたクライアント ID を指定します。
- [ステップ 1] セクションで、Google スコープは選択しないでください。代わりに、このフィールドを空白のままにするか、サーバーで有効なスコープを入力します(OAuth スコープを使用しない場合は任意の文字列を入力します)。完了したら、[API を承認] をクリックします。
- ステップ 2 とステップ 3 のセクションで OAuth 2.0 フローを実行し、各ステップが意図したとおりに機能することを確認します。
実装を検証するには、Google アカウント リンクのデモツールを使用します。
ツールで次の操作を行います。
- [Google でログイン] ボタンをクリックします。
- リンクするアカウントを選択します。
- サービス ID を入力します。
- 必要に応じて、アクセスをリクエストするスコープを 1 つ以上入力します。
- [デモを開始] をクリックします。
- リンク リクエストに同意できることを確認して、リクエストを拒否します。
- プラットフォームにリダイレクトされることを確認します。