リンクされたアカウントへのログイン

Google アカウントのリンクにより、Google アカウントの所有者は迅速かつシームレスかつ安全にサービスに接続し、Google とデータを共有できます。

リンクされたアカウントのログインにより、すでに Google アカウントがサービスにリンクされているユーザーに対して Google でワンタップでログインできます。ユーザーはユーザー名とパスワードを再入力することなく、ワンクリックでログインできるため、ユーザー エクスペリエンスが向上します。また、ユーザーがサービス上に重複アカウントを作成する可能性も低くなります。

要件

リンクされたアカウントのログインを実装するには、次の要件を満たす必要があります。

仕組み

前提条件 : ユーザーが以前に自分の Google アカウントとサービスのアカウントをリンクしたことがある。

  1. ワンタップのログインフローで、リンクされたアカウントの表示を有効にしました。
  2. ワンタップ ログインのプロンプトが表示され、リンクされているアカウントでサービスにログインできます。
  3. ユーザーがリンクされたアカウントで続行する場合、Google は認証コードを保存するリクエストをトークン エンドポイントに送信します。リクエストには、サービスによって発行されたユーザーのアクセス トークンと Google 認証コードが含まれます。
  4. Google 認証コードを、ユーザーの Google アカウントに関する情報を含む Google ID トークンと交換します。
  5. フローが終了すると、アプリは ID トークンを受け取ります。この ID をユーザー ID と照合すると、ユーザーをアプリにログインさせることができます。
リンクされたアカウントへのログイン
図 1.リンク済みアカウントのログインフロー。ユーザーがデバイスに複数のログイン アカウントを持っている場合、アカウント選択ツールが表示され、リンクされたアカウントを選択した場合にのみ [リンクされたアカウントのログイン] ビューが表示されます。

Android アプリにリンクされたアカウント ログインを実装する

Android アプリでリンクされたアカウント ログインをサポートするには、Android 実装ガイドの手順に沿って対応してください。

Google からの認証コード リクエストを処理する

Google は、ユーザーの ID トークンと交換する認証コードを保存するために、トークン エンドポイントに POST リクエストを行います。リクエストには、ユーザーのアクセス トークンと Google が発行した OAuth2 認証コードが含まれます。

認証コードを保存する前に、client_id によって識別されるアクセス トークンが Google に付与されたことを確認する必要があります。

HTTP リクエスト

リクエストの例

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

code=GOOGLE_AUTHORIZATION_CODE
&grant_type=urn:ietf:params:oauth:grant-type:reciprocal
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
&access_token=ACCESS_TOKEN

トークン交換エンドポイントは、次のリクエスト パラメータを処理できる必要があります。

トークン交換エンドポイントのパラメータ
code 必須: Google OAuth2 認証コード
client_id 必須: Google に発行したクライアント ID
client_secret 必須 Google に発行したクライアント シークレット
access_token 必須: Google に発行したアクセス トークン。これを使用して、ユーザーのコンテキストを取得します。
grant_type 必須 値を urn:ietf:params:oauth:grant-type:reciprocal に設定する必要があります。

トークン交換エンドポイントは、次のように POST リクエストに応答する必要があります。

  • client_id によって識別される access_token が Google に付与されていることを確認します。
  • リクエストが有効で、認証コードが Google ID トークンと正常に交換されている場合は HTTP 200(OK)レスポンスを、無効な場合は HTTP エラーコードで応答する。

HTTP レスポンス

成功

HTTP ステータス コード 200 OK を返す

成功のレスポンスの例
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{}

エラー

無効な HTTP リクエストの場合は、次のいずれかの HTTP エラーコードで応答します。

HTTP ステータス コード Body Description
400 {"error": "invalid_request"} リクエストにパラメータがないため、サーバーでリクエストを処理できなくなります。サポートされていないパラメータがリクエストに含まれている場合や、パラメータが繰り返される場合にも返されることがあります。
401 {"error": "invalid_request"} クライアント認証に失敗した(リクエストに無効なクライアント ID やシークレットが含まれている場合など)
401 {"error": "invalid_token"}

WWW 認証: 署名なしの認証リクエストをレスポンス ヘッダーに含める

パートナー アクセス トークンが無効です。
403 {"error": "insufficient_permission"}

WWW 認証: 署名なしの認証リクエストをレスポンス ヘッダーに含める

パートナー アクセス トークンに、相互 OAuth を実行するために必要なスコープが含まれていません
500 {"error": "internal_error"} サーバーエラー

エラー レスポンスには次のフィールドが含まれます。

エラー レスポンス フィールド
error 必須 エラー文字列
error_description 人が読める形式のエラーの説明
error_uri エラーの詳細を提供する URI
エラー 400 レスポンスの例
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "error": "invalid_request",
  "error_description": "Request was missing the 'access_token' parameter."
}

ID トークンの交換コードの認証

受け取った認証コードは、ユーザーの Google アカウントに関する情報を含む Google ID トークンと交換する必要があります。

認証コードを Google ID トークンと交換するには、https://oauth2.googleapis.com/token エンドポイントを呼び出して、次のパラメータを設定します。

リクエスト フィールド
client_id 必須: API Console の [認証情報] ページから取得したクライアント ID。通常は、「New Actions on Google App」という名前の認証情報です。
client_secret 必須: API Console の [認証情報] ページから取得したクライアント シークレット
code 必須 最初のリクエストで送信される認証コード
grant_type 必須 OAuth 2.0 仕様で定義されているように、このフィールドの値は authorization_code に設定する必要があります。
リクエストの例
POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=GOOGLE_AUTHORIZATION_CODE
&grant_type=authorization_code
&client_id=GOOGLE_CLIENT_ID
&client_secret=GOOGLE_CLIENT_SECRET

Google は、このリクエストに対して、有効期間の短いアクセス トークンと更新トークンを含む JSON オブジェクトを返します。

レスポンスには、次のフィールドが含まれます。

レスポンス フィールド
access_token アプリケーションが Google API リクエストを承認するために送信する Google 発行のアクセス トークン
id_token ID トークンには、ユーザーの Google アカウント情報が含まれます。ID トークンのレスポンスをデコードして検証する方法については、レスポンスの検証をご覧ください
expires_in アクセス トークンの有効期間(秒)
refresh_token 新しいアクセス トークンの取得に使用できるトークン。更新トークンは、ユーザーがアクセス権を取り消すまで有効です
scope このフィールドの値は、リンクされたアカウント ログインのユースケースでは常に openid に設定されます。
token_type 返されるトークンのタイプ。現時点では、このフィールドは常に Bearer に設定されています
サンプル レスポンス
HTTP/1.1 200 OK
Content-type: application/json; charset=utf-8

{
  "access_token": "Google-access-token",
  "id_token": "Google-ID-token",
  "expires_in": 3599,
  "token_type": "Bearer",
  "scope": "openid",
  "refresh_token": "Google-refresh-token"
}


POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=Google authorization code
&grant_type=authorization_code
&client_id=Google client id
&client_secret=Google client secret

ID トークンのレスポンスを検証する

JWTアサーションを検証してデコードします

言語のJWTデコードライブラリを使用して、JWTアサーションを検証およびデコードできますJWKまたはPEM形式で利用可能なGoogleの公開鍵を使用して、トークンの署名を確認します。

デコードすると、JWTアサーションは次の例のようになります:

{
  "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
}

トークンの署名の確認に加えて、アサーションの発行者( issフィールド)がhttps://accounts.google.comであること、オーディエンス( audフィールド)が割り当てられたクライアントIDであること、トークンの有効期限が切れていないこと( expフィールド)。

emailemail_verifiedhdフィールドを使用して、Googleがメールアドレスをホストしていて権限があるかどうかを判断できます。 Googleが信頼できる場合、ユーザーは現在正当なアカウント所有者であることがわかっており、パスワードやその他のチャレンジ方法をスキップできます。それ以外の場合は、これらの方法を使用して、リンクする前にアカウントを確認できます。

Googleが権威を持っている場合:

  • emailには@gmail.comサフィックスが付いています。これはGmailアカウントです。
  • email_verifiedがtrueで、 hdが設定されている場合、これはemail_verifiedアカウントです。

ユーザーはGmailやGSuiteを使用せずにGoogleアカウントに登録できます。 email @gmail.comサフィックスが含まれておらず、 hdがない場合、Googleは信頼できません。ユーザーを確認するには、パスワードまたはその他のチャレンジ方法をお勧めします。 email_verfiedは、Googleアカウントが作成されたときにGoogleが最初にユーザーを確認したため、trueになることもありますが、サードパーティの電子メールアカウントの所有権が変更された可能性があります。