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

図 1. ユーザーのスマートフォンでのアカウントのリンクの簡素化
リンクを合理化するための要件
- 基本的なウェブ OAuth リンクのフローを実装するサービスが OAuth 2.0 準拠の承認エンドポイントとトークン交換エンドポイントをサポートしている必要があります。
- トークン交換エンドポイントは、JSON ウェブトークン(JWT)アサーションをサポートし、
check
、create
、get
インテントを実装する必要があります。
OAuth サーバーを実装する
トークン交換エンドポイントは、check
、create
、get
インテントをサポートしている必要があります。以下に、アカウント リンクのフローに従って完了した手順と、さまざまなインテントが呼び出されたタイミングを示します。
- ユーザーの認証システムにアカウントはありますか?(ユーザーが「はい」または「いいえ」を選択したとき)。
- はい : ユーザーが Google アカウントに関連付けられているメールアドレスを使用してプラットフォームにログインしていますか?(ユーザーが「はい」または「いいえ」を選択したとき)。
- はい : お客様の認証システムに一致するアカウントはありますか?(確認のために
check intent
が呼び出されます)- YES :
get intent
が呼び出され、get インテントが正常に返された場合、アカウントはリンクされています。 - いいえ : 新しいアカウントを作成しますか?(ユーザーが「はい」または「いいえ」を選択したとき)。
- YES:
create intent
が呼び出され、作成インテントが正常に返された場合、アカウントはリンクされています。 - いいえ : ウェブ OAuth フローがトリガーされ、ユーザーはブラウザにリダイレクトされます。別のメールにリンクするオプションがユーザーに表示されます。
- YES:
- YES :
- いいえ : ウェブの OAuth フローがトリガーされ、ユーザーはブラウザにリダイレクトされます。別のメールにリンクするオプションがユーザーに表示されます。
- はい : お客様の認証システムに一致するアカウントはありますか?(確認のために
- いいえ : 認証システムに登録されているユーザーと一致するアカウントはありますか?(確認のために
check intent
が呼び出されます)- YES:
get intent
が呼び出され、get インテントが正常に返された場合、アカウントはリンクされています。 - × :
create intent
が呼び出され、作成インテントが正常に返された場合、アカウントはリンクされています。
- YES:
- はい : ユーザーが Google アカウントに関連付けられているメールアドレスを使用してプラットフォームにログインしていますか?(ユーザーが「はい」または「いいえ」を選択したとき)。
既存のユーザー アカウントを確認する(インテントを確認する)
ユーザーが 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 アカウントがすでに存在するかどうかを確認します。
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 アカウントが認証システムに存在するかどうかの確認
次のいずれかの条件を満たしていることを確認します。
- アサーションの
sub
フィールドにある Google アカウント ID が、ユーザー データベースにあります。 - アサーションに含まれているメールアドレスが、ユーザーのデータベースに登録されているユーザーと一致している。
いずれかの条件を満たしていれば、ユーザーはすでに登録しています。その場合、次のようなレスポンスが返されます。
HTTP/1.1 200 Success Content-Type: application/json;charset=UTF-8 { "account_found":"true", }
Google アカウント ID とアサーションで指定されたメールアドレスのいずれもデータベース内のユーザーと一致しない場合、ユーザーはまだ登録していません。その場合、トークン交換エンドポイントは "account_found": "false"
を指定する HTTP 404 エラーを返す必要があります。次に例を示します。
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&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET
トークン交換エンドポイントでは、以下のパラメータを処理する必要があります。
トークン交換エンドポイントのパラメータ | |
---|---|
intent |
このリクエストの場合、このパラメータの値は get です。 |
grant_type |
交換されるトークンの種類。これらのリクエストの場合、このパラメータの値は urn:ietf:params:oauth:grant-type:jwt-bearer になります。 |
assertion |
Google ユーザー ID の署名付きアサーションを提供する JSON Web Token(JWT)。JWT には、ユーザーの Google アカウント ID、名前、メールアドレスなどの情報が含まれています。 |
scope |
省略可: ユーザーにリクエストするように Google が構成したスコープ。 |
client_id |
Google に割り当てたクライアント ID。 |
client_secret |
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 アカウントが認証システムに存在するかどうかの確認
次のいずれかの条件を満たしていることを確認します。
- アサーションの
sub
フィールドにある Google アカウント ID が、ユーザー データベースにあります。 - アサーションに含まれているメールアドレスが、ユーザーのデータベースに登録されているユーザーと一致している。
ユーザーのアカウントが見つかった場合は、アクセス トークンを発行して、HTTPS レスポンス本文の JSON オブジェクトに値を返します(例:
{ "token_type": "Bearer", "access_token": "ACCESS_TOKEN", "expires_in": SECONDS_TO_EXPIRATION })。
場合によっては、ID トークンに基づくアカウントのリンクが失敗することがあります。なんらかの理由で存在する場合、トークン交換エンドポイントは error=linking_error
を指定する HTTP 401 エラーで応答する必要があります。次に例を示します。
HTTP/1.1 401 Unauthorized Content-Type: application/json;charset=UTF-8 { "error":"linking_error", "login_hint":"foo@bar.com" }
Google が linking_error
で 401 エラー レスポンスを受け取ると、パラメータとして 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&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET
トークン交換エンドポイントは次のパラメータを処理できる必要があります。
トークン交換エンドポイントのパラメータ | |
---|---|
intent |
このリクエストの場合、このパラメータの値は create です。 |
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 に割り当てたクライアント シークレット。 |
assertion
パラメータ内の JWT には、ユーザーの Google アカウント ID、名前、メールアドレスが含まれます。これらの 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になることもありますが、サードパーティの電子メールアカウントの所有権が変更された可能性があります。
ユーザー情報を検証して新しいアカウントを作成する
次のいずれかの条件を満たしていることを確認します。
- アサーションの
sub
フィールドにある Google アカウント ID が、ユーザー データベースにあります。 - アサーションに含まれているメールアドレスが、ユーザーのデータベースに登録されているユーザーと一致している。
いずれかの条件に当てはまる場合は、既存のアカウントと Google アカウントをリンクするよう促します。これを行うには、error=linking_error
を指定し、ユーザーのメールアドレスを login_hint
として指定する HTTP 401 エラーを返します。レスポンスの例を次に示します。
HTTP/1.1 401 Unauthorized Content-Type: application/json;charset=UTF-8 { "error":"linking_error", "login_hint":"foo@bar.com" }
Google が linking_error
で 401 エラー レスポンスを受け取ると、パラメータとして 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つ以上のスコープを入力します。
- スタートデモをクリックしてください。
- プロンプトが表示されたら、リンク要求に同意して拒否できることを確認します。
- プラットフォームにリダイレクトされていることを確認します。