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

概要

OAuthのベースのGoogleサインイン合理化のリンクは上部のグーグルサインインを追加するのOAuthリンク。これにより、Googleユーザーにシームレスなリンクエクスペリエンスが提供され、アカウントの作成も可能になります。これにより、ユーザーはGoogleアカウントを使用してサービスに新しいアカウントを作成できます。

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

  1. まず、ユーザーにGoogleプロフィールへのアクセスに同意するよう依頼します。
  2. プロファイルの情報を使用して、ユーザーアカウントが存在するかどうかを確認します。
  3. 既存のユーザーの場合は、アカウントをリンクします。
  4. 認証システムでGoogleユーザーに一致するものが見つからない場合は、Googleから受け取ったIDトークンを検証してください。次に、IDトークンに含まれているプロファイル情報に基づいてユーザーを作成できます。
この図は、合理化されたリンクフローを使用してユーザーがGoogleアカウントをリンクするための手順を示しています。最初のスクリーンショットは、ユーザーがリンクするアプリを選択する方法を示しています。 2番目のスクリーンショットでは、ユーザーがサービスに既存のアカウントを持っているかどうかを確認できます。 3番目のスクリーンショットでは、ユーザーはリンク先のGoogleアカウントを選択できます。 4番目のスクリーンショットは、Googleアカウントをアプリにリンクするための確認を示しています。 5番目のスクリーンショットは、Googleアプリで正常にリンクされたユーザーアカウントを示しています。

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

合理化されたリンクの要件

OAuthサーバーを実装する

あなたのトークン交換エンドポイントがサポートしている必要がありますcheckcreategetの意図を。以下は、アカウントリンクフローを通じて完了した手順を示し、さまざまなインテントがいつ呼び出されるかを示しています。

  1. ユーザーは認証システムにアカウントを持っていますか? (ユーザーは[はい]または[いいえ]を選択して決定します)
    1. はい:ユーザーは自分のGoogleアカウントに関連付けられたメールを使用してプラットフォームにサインインしますか? (ユーザーは[はい]または[いいえ]を選択して決定します)
      1. はい:ユーザーは認証システムに一致するアカウントを持っていますか? ( check intent確認するために呼ばれています)
        1. YES: get intentと呼ばれ、成功裏に意図リターンを得る場合は、アカウントがリンクされています。
        2. いいえ:新しいアカウントを作成しますか? (ユーザーは[はい]または[いいえ]を選択して決定します)
          1. YES: create intentと呼ばれ、成功裏に意図リターンを作成する場合、アカウントがリンクされています。
          2. いいえ:Web OAuthフローがトリガーされ、ユーザーはブラウザーに誘導され、ユーザーには別の電子メールにリンクするオプションが与えられます。
      2. NO:ウェブOAuthのフローがトリガされ、ユーザーは自分のブラウザに送られ、ユーザーは別の電子メールとのリンクにオプションを与えています。
    2. いいえ:ユーザーは認証システムに一致するアカウントを持っていますか? ( check intent確認するために呼ばれています)
      1. YES: get intentと呼ばれ、成功裏に意図リターンを得る場合は、アカウントがリンクされています。
      2. NO: create intentと呼ばれ、成功裏に意図リターンを作成する場合、アカウントがリンクされています。

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

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

対応のGoogleアカウントには、お使いの認証システムで、既にを使用してトークンの交換エンドポイントの応答が存在する場合account_found=true 。 Googleのアカウントが既存のユーザーと一致しない場合は、お使いのトークン交換エンドポイントは、とHTTP 404 Not Foundエラーを返し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アサーションを検証してデコードします。
  • Googleアカウントが認証システムにすでに存在するかどうかを確認してください。
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アカウントが認証システムにすでに存在するかどうかを確認します

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

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

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

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

自動リンクを処理する(意図を得る)

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

対応するGoogleアカウントが認証システムにすでに存在する場合、トークン交換エンドポイントはユーザーのトークンを返します。 Googleアカウントが既存のユーザーと一致しない場合は、お使いのトークン交換エンドポイントが返されますlinking_errorエラーとオプションlogin_hint

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

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

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

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

対応するためにget意思の要求を、あなたのトークン交換エンドポイントは、次の手順を実行する必要があります。

  • JWTアサーションを検証してデコードします。
  • Googleアカウントが認証システムにすでに存在するかどうかを確認してください。
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アカウントが認証システムにすでに存在するかどうかを確認します

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

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

アカウントがユーザーのために発見された場合、アクセストークンを発行し、次の例のように、あなたのHTTPS応答のボディにJSONオブジェクトに値を返す:

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

  "expires_in": SECONDS_TO_EXPIRATION
}

場合によっては、IDトークンに基づくアカウントのリンクがユーザーにとって失敗することがあります。それが何らかの理由でそうする場合は、あなたのトークン交換エンドポイントを指定することをHTTP 401エラーで応答する必要がありますerror=linking_error次の例が示すように、:

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リンクフローを使用してアカウントのリンクを完了します。

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、名前、および電子メールアドレスが含まれています。

対応するためにcreate意図の要求を、あなたのトークン交換エンドポイントは、次の手順を実行する必要があります。

  • 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アカウント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",

  "expires_in": SECONDS_TO_EXPIRATION
}

GoogleAPIクライアントIDを取得します

あなたは、アカウント・リンクの中にはGoogle APIクライアントIDを提供する必要があります登録プロセス。

完成しながら、あなたが作成したプロジェクト使用して、APIのクライアントIDを取得するにはOAuthのリンクの手順を。これを行うには、次の手順を実行します。

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

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

実装の検証

あなたは使用して実装を検証することができOAuth 2.0の遊び場のツールを。

ツールで、次の手順を実行します。

  1. 設定をクリックし OAuth 2.0の設定]ウィンドウを開きます。
  2. OAuthの流れ場では、クライアント側を選択します。
  3. OAuthのエンドポイント]フィールドで、[カスタム]を選択します。
  4. OAuth2.0エンドポイントとGoogleに割り当てたクライアントIDを対応するフィールドに指定します。
  5. ステップ1セクションでは、すべてのGoogleサービスのスコープを選択しないでください。代わりに、このフィールドを空白のままにするか、サーバーに有効なスコープ(または、OAuthスコープを使用しない場合は任意の文字列)を入力してください。設定が完了したら、承認のAPIをクリックします。
  6. ステップ2ステップ3のセクションでは、OAuth 2.0のフローを通過し、意図したように各ステップが動作することを確認。

あなたは使用して実装を検証することができ、Googleアカウントのリンクデモツールを。

ツールで、次の手順を実行します。

  1. Googleのボタンでサインインしをクリックしてください。
  2. リンクするアカウントを選択してください。
  3. サービスIDを入力します。
  4. オプションで、アクセスを要求する1つ以上のスコープを入力します。
  5. スタートデモをクリックしてください。
  6. プロンプトが表示されたら、リンク要求に同意して拒否できることを確認します。
  7. プラットフォームにリダイレクトされていることを確認します。