OAuthとGoogleサインインによる合理化されたリンク

概要

OAuthのベースのGoogleサインイン合理化のリンクは上部のグーグルサインインを追加するのOAuthリンク。これにより、Googleユーザーにシームレスなリンクエクスペリエンスが提供され、Google以外のIDでサービスに登録したユーザーのアカウントリンクも可能になります。

OAuthおよびGoogleサインインを使用してアカウントのリンクを実行するには、次の一般的な手順に従います。

  1. まず、ユーザーにGoogleプロフィールへのアクセスに同意するよう依頼します。
  2. プロファイルの情報を使用して、ユーザーアカウントが存在するかどうかを確認します。
  3. 既存のユーザーの場合は、アカウントをリンクします。
  4. 認証システムでGoogleユーザーに一致するものが見つからない場合は、Googleから受け取ったIDトークンを検証してください。次に、IDトークンに含まれているプロファイル情報に基づいてユーザーを作成できます。

図3。合理化されたリンクを使用したユーザーの電話でのアカウントリンク

アカウントは2.0暗黙的および認証コードが流れ、業界標準のOAuthを使用してリンクされています。あなたのサービスは、OAuth 2.0の準拠の認証トークン交換のエンドポイントをサポートしている必要があります。また、あなたのトークン交換エンドポイントがサポートする必要がありますJSONウェブトークン(JWT)アサーションをし、実装checkcreate 、およびgetの意図を。

GoogleAPIクライアントIDとシークレットを取得する

あなたは完了している間、あなたが作成したプロジェクト使用して、APIクライアントIDとシークレットを取得する必要がありますOAuthのリンクの手順を。これを行うには、次の手順を実行します。

  1. 資格情報]ページを開き、GoogleのAPIコンソールを
  2. GoogleAPIプロジェクトを作成または選択します。

    あなたのプロジェクトは、Webアプリケーションの種類のクライアントIDを持っていない場合は、資格証明書の作成]クリックします>のOAuthクライアントIDは1を作成します。認定JavaScriptの起源はボックスにサイトのドメインを含めるようにしてください。あなたはローカルのテストや開発を行う際には、追加する必要があり、両方http://localhostしてhttp://localhost:<port_number>認定JavaScriptの起源フィールドへ。

OAuthサーバーを実装する

既存のユーザーアカウントを確認します

ユーザーがGoogleプロフィールへのアクセスに同意すると、GoogleはGoogleユーザーのIDの署名されたアサーションを含むリクエストを送信します。アサーションには、ユーザーのGoogleアカウントID、名前、メールアドレスなどの情報が含まれています。プロジェクト用に構成されたトークン交換エンドポイントがその要求を処理します。

対応するGoogleアカウントが認証システムにすでに存在する場合、トークン交換エンドポイントはaccount_found=true応答しaccount_found=true 。 Googleアカウントが既存のユーザーと一致しない場合、トークン交換エンドポイントは、 account_found=falseaccount_found=falseエラーをaccount_found=false

リクエストの形式は次のとおりです。

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

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

トークンエンドポイントパラメーター
intentこれらのリクエストの場合、このパラメータの値はcheckです。
grant_type交換されるトークンのタイプ。これらのリクエストの場合、このパラメーターの値はurn:ietf:params:oauth:grant-type:jwt-bearerです。
assertion GoogleユーザーのIDの署名されたアサーションを提供するJSONWeb Token(JWT)。 JWTには、ユーザーのGoogleアカウントID、名前、メールアドレスなどの情報が含まれています。

トークン交換エンドポイントがcheckリクエストを受信すると、JWTアサーションを検証してデコードする必要があります。

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になることもありますが、サードパーティの電子メールアカウントの所有権が変更された可能性があります。

Googleアカウントが認証システムにすでに存在するかどうかを確認します

次の条件のいずれかが当てはまるかどうかを確認します。

  • アサーションのsubフィールドにあるGoogleアカウントIDは、ユーザーデータベースにあります。
  • アサーションの電子メールアドレスは、ユーザーデータベースのユーザーと一致します。

いずれかの条件が真の場合、ユーザーはすでにサインアップしています。その場合、次のような応答を返します。

HTTP/1.1 200 Success
Content-Type: application/json;charset=UTF-8

{
  "account_found":"true",
}

次に、Googleはユーザーにリンク同意ダイアログを表示し、リンクを続行するために目的のスコープの同意を要求します。 Googleがユーザーの同意を取得した後、Googleはリンクを続行するためにトークンエンドポイントにgetリクエストを送信します。

アサーションで指定されたGoogleアカウントIDもメールアドレスもデータベース内のユーザーと一致しない場合、そのユーザーはまだサインアップしていません。この場合、トークン交換エンドポイントは、次の例のように、 "account_found": "false"を指定する"account_found": "false"エラーで応答する必要があります。

HTTP/1.1 404 Not found
Content-Type: application/json;charset=UTF-8

{
  "account_found":"false",
}
Googleが"account_found": "false"エラーで404エラー応答を受信すると、Googleはユーザーにダイアログを表示して、新しいアカウントを作成し、目的のスコープにアクセスすることへの同意を要求します。 Googleがユーザーの同意を取得した後、Googleは、 create intentパラメータの値を使用してトークン交換エンドポイントを呼び出し、リクエストにユーザーのプロファイル情報を含むIDトークンを含めます。

Handle automatic linking

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

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.

When your token exchange endpoint receives the linking request, it needs to validate and decode the JWT assertion.

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になることもありますが、サードパーティの電子メールアカウントの所有権が変更された可能性があります。

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.

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 calls your token exchange endpoint with the following in the request:

  • The intent parameter set to create
  • A JWT with the ID token and user's profile information

Googleサインインを介してアカウントの作成を処理する

ユーザーがあなたのサービスのアカウントを作成する必要がある場合、Googleが指定されていることを、あなたのトークン交換エンドポイントに要求を行うintent=create

リクエストの形式は次のとおりです。

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

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

トークンエンドポイントパラメーター
intentこれらの要求のために、このパラメータの値があるcreate
grant_type交換されるトークンのタイプ。これらの要求のために、このパラメータは、値があるurn:ietf:params:oauth:grant-type:jwt-bearer
assertion GoogleユーザーのIDの署名されたアサーションを提供するJSONWeb Token(JWT)。 JWTには、ユーザーのGoogleアカウントID、名前、メールアドレスなどの情報が含まれています。

内のJWT assertionパラメータを使用すると、あなたのサービスに新しいアカウントを作成するために使用することができ、ユーザーのGoogleアカウントID、名前、および電子メールアドレスが含まれています。

アカウント作成リクエストに応答するには、トークン交換エンドポイントが次の2つのセクションの手順を実行する必要があります。

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になることもありますが、サードパーティの電子メールアカウントの所有権が変更された可能性があります。

ユーザー情報を検証し、新しいアカウントを作成します

次の条件のいずれかが当てはまるかどうかを確認します。

  • アサーションので見つかったGoogleアカウントID、 subフィールドは、ユーザーデータベースです。
  • アサーションの電子メールアドレスは、ユーザーデータベースのユーザーと一致します。

いずれかの条件が当てはまる場合は、既存のアカウントをGoogleアカウントにリンクするようにユーザーに促します。これを行うには、HTTP 401エラーことを指定すると、要求に応答するerror=linking_errorとしてユーザーの電子メールアドレスを与えるlogin_hint 。応答の例を次に示します。

HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8

{
  "error":"linking_error",
  "login_hint":"foo@bar.com"
}

Googleが持つ401エラーレスポンスを受信するとlinking_error 、Googleがして、あなたの認可エンドポイントにユーザーを送信しlogin_hintパラメータとして。ユーザーは、ブラウザのOAuthリンクフローを使用してアカウントのリンクを完了します。

どちらの条件も当てはまらない場合は、JWTで提供される情報を使用して新しいユーザーアカウントを作成します。通常、新しいアカウントにはパスワードが設定されていません。他のプラットフォームにGoogleサインインを追加して、ユーザーがアプリケーションの表面全体でGoogleにログインできるようにすることをお勧めします。または、パスワード回復フローを開始するリンクをユーザーに電子メールで送信して、ユーザーが他のプラットフォームにサインインするためのパスワードを設定できるようにすることもできます。

作成が完了すると、アクセストークン発行 とリフレッシュトークン し、次の例のように、あなたのHTTPS応答のボディにJSONオブジェクトに値を返す:

{
  "token_type": "Bearer",
  "access_token": "ACCESS_TOKEN",

  "refresh_token": "REFRESH_TOKEN",

  "expires_in": SECONDS_TO_EXPIRATION
}

実装の検証

You can validate your implementation by using the OAuth 2.0 Playground tool.

In the tool, do the following steps:

  1. Click Configuration to open the OAuth 2.0 Configuration window.
  2. In the OAuth flow field, select Client-side.
  3. In the OAuth Endpoints field, select Custom.
  4. Specify your OAuth 2.0 endpoint and the client ID you assigned to Google in the corresponding fields.
  5. In the Step 1 section, don't select any Google scopes. Instead, leave this field blank or type a scope valid for your server (or an arbitrary string if you don't use OAuth scopes). When you're done, click Authorize APIs.
  6. In the Step 2 and Step 3 sections, go through the OAuth 2.0 flow and verify that each step works as intended.

You can validate your implementation by using the Google Account Linking Demo tool.

In the tool, do the following steps:

  1. Click the Sign-in with Google button.
  2. Choose the account you'd like to link.
  3. Enter the service ID.
  4. Optionally enter one or more scopes that you will request access for.
  5. Click Start Demo.
  6. When prompted, confirm that you may consent and deny the linking request.
  7. Confirm that you are redirected to your platform.