概要
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
が呼び出されます)。- はい :
get intent
が呼び出され、get インテントが正常に返された場合、アカウントはリンクされています。 - いいえ : 新しいアカウントを作成しますか?(ユーザーが「はい」か「いいえ」を選択して決定)
- はい:
create intent
が呼び出され、作成インテントが正常に返された場合、アカウントをリンクしています。 - いいえ : ウェブ OAuth フローがトリガーされ、ユーザーはブラウザに誘導され、ユーザーは別のメールとリンクできます。
- はい:
- はい :
- いいえ : ウェブ OAuth フローがトリガーされ、ユーザーはブラウザに誘導され、別のメールにリンクするオプションが表示されます。
- はい : ユーザーの認証システムに登録されているアカウントが一致していますか?(確認の目的で
- いいえ : ユーザーの認証システムに登録されているアカウントがあるか(確認の目的で
check intent
が呼び出されます)。- はい:
get intent
が呼び出され、get インテントが正常に返された場合、アカウントはリンクされています。 - いいえ : インテントが正常に返された場合は
create intent
が呼び出され、アカウントがリンクされます。
- はい:
- はい : プラットフォームにログインする際に、ユーザーは Google アカウントに関連付けられているメールアドレスを使用しますか?(ユーザーが「はい」か「いいえ」を選択して決定)
既存のユーザーアカウントを確認します(意図を確認します)
ユーザーが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
フィールド)。
email
、 email_verified
、 hd
フィールドを使用して、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
フィールド)。
email
、 email_verified
、 hd
フィールドを使用して、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
フィールド)。
email
、 email_verified
、 hd
フィールドを使用して、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 }
Google API クライアント ID を取得する
アカウントのリンクの登録プロセスで、Google API クライアント ID を入力していただく必要があります。
OAuth リンクの手順を行いながら、作成したプロジェクトを使って API クライアント ID を取得します。そのための手順は次のとおりです。
- Google API Console の [認証情報] ページを開きます。
Google API プロジェクトを作成または選択します。
プロジェクトにウェブ アプリケーション タイプのクライアント ID がない場合は、[認証情報を作成&OAuth クライアント ID] をクリックして作成します。必ず [承認済みの JavaScript 生成元] ボックスにサイトのドメインを含めてください。ローカルテストまたは開発を行う場合は、
http://localhost
とhttp://localhost:<port_number>
の両方を [承認済みの JavaScript 生成元] フィールドに追加する必要があります。
実装の検証
あなたは使用して実装を検証することができOAuth 2.0の遊び場のツールを。
ツールで、次の手順を実行します。
- 設定をクリックし OAuth 2.0の設定]ウィンドウを開きます。
- OAuthの流れ場では、クライアント側を選択します。
- OAuthのエンドポイント]フィールドで、[カスタム]を選択します。
- OAuth2.0エンドポイントとGoogleに割り当てたクライアントIDを対応するフィールドに指定します。
- ステップ1セクションでは、すべてのGoogleサービスのスコープを選択しないでください。代わりに、このフィールドを空白のままにするか、サーバーに有効なスコープ(または、OAuthスコープを使用しない場合は任意の文字列)を入力してください。設定が完了したら、承認のAPIをクリックします。
- ステップ2とステップ3のセクションでは、OAuth 2.0のフローを通過し、意図したように各ステップが動作することを確認。
あなたは使用して実装を検証することができ、Googleアカウントのリンクデモツールを。
ツールで、次の手順を実行します。
- Googleのボタンでサインインしをクリックしてください。
- リンクするアカウントを選択してください。
- サービスIDを入力します。
- オプションで、アクセスを要求する1つ以上のスコープを入力します。
- スタートデモをクリックしてください。
- プロンプトが表示されたら、リンク要求に同意して拒否できることを確認します。
- プラットフォームにリダイレクトされていることを確認します。