バックエンド サーバーで認証する

バックエンドと通信するアプリやサイトで Google ログインを使用する場合 現在ログインしているユーザーを特定する必要があります。 これを安全に行うために、ユーザーがログインに成功したら、ユーザーの HTTPS を使用してサーバーに送信される ID トークン。次に、サーバーで整合性を検証し、 トークンに含まれるユーザー情報を使用して、独自の ID トークンを 新しいアカウントを作成することもできます。

ID トークンをサーバーに送信する

ユーザーが正常にログインしたら、ユーザーの ID トークンを取得します。

function onSignIn(googleUser) {
  var id_token = googleUser.getAuthResponse().id_token;
  ...
}

次に、HTTPS POST リクエストで ID トークンをサーバーに送信します。

var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://yourbackend.example.com/tokensignin');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
  console.log('Signed in as: ' + xhr.responseText);
};
xhr.send('idtoken=' + id_token);

ID トークンの整合性を確認する

HTTPS POST で ID トークンを受信したら、完全性を検証する必要があります。 渡されます。

トークンが有効であることを確認するには、次のことを確認します。 条件が満たされます。

  • ID トークンが Google によって適切に署名されている。Google の公開鍵を使用する ( JWK または PEM 形式) トークンの署名を検証します。これらの鍵は定期的にローテーションされます。調べる レスポンスの Cache-Control ヘッダーを使用して、 再度取得する必要があります
  • ID トークンの aud の値がアプリのいずれかの値と等しい クライアント ID などがあります。このチェックは、悪意のあるクライアントに ID トークンを発行するのを防ぐために必要です。 アプリが、アプリのバックエンド サーバー上の同一ユーザーに関するデータにアクセスするために使用されています。
  • ID トークンの iss の値は次と等しい accounts.google.com または https://accounts.google.com
  • ID トークンの有効期限(exp)を過ぎていない。
  • ID トークンが Google Workspace または Cloud 組織アカウントの場合は、hd クレームを確認できます。これは、ホストされている Pod が ユーザーのドメインです。これは、リソースへのアクセスをそのメンバーのみに制限する場合に できます。このクレームがない場合、アカウントは Google がホストするドメイン。

emailemail_verifiedhd フィールドを使用して、 Google はメールアドレスをホストし、その権威があります。Google が信頼できる場合、 そのユーザーが正当なアカウント所有者であることがわかっているため、パスワードやその他の 確認しましょう。

Google が信頼できるケース:

  • email には @gmail.com という接尾辞が付いています。これは Gmail アカウントです。
  • email_verified は true で、hd が設定されています。これは G Suite アカウントです。

ユーザーは Gmail や G Suite を使用せずに Google アカウントを登録できます。日時 email@gmail.com という接尾辞がなく、hd が存在しないと、Google にはありません。 認証には、信頼できる認証方法、パスワード、その他の本人確認方法を使用することが推奨されます。 できます。email_verified も、Google が最初に検証した ユーザーに付与できますが、サードパーティの所有権が付与されます。 アカウントが変更された可能性があります。

これらの検証ステップを実行するために独自のコードを記述するのではなく、 プラットフォームに適した Google API クライアント ライブラリを使用するか、 JWT ライブラリ。開発とデバッグの場合は、tokeninfo を呼び出すことができます。 検証エンドポイントを指定します。

使用 Google API 客户端库

使用某个 Google API 客户端库(例如 JavaNode.jsPHPPython) 是在生产环境中验证 Google ID 令牌的推荐方法。

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Java

要在 Java 中验证 ID 令牌,请使用 GoogleIdTokenVerifier 对象。例如:

import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;

...

GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
    // Specify the CLIENT_ID of the app that accesses the backend:
    .setAudience(Collections.singletonList(CLIENT_ID))
    // Or, if multiple clients access the backend:
    //.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
    .build();

// (Receive idTokenString by HTTPS POST)

GoogleIdToken idToken = verifier.verify(idTokenString);
if (idToken != null) {
  Payload payload = idToken.getPayload();

  // Print user identifier
  String userId = payload.getSubject();
  System.out.println("User ID: " + userId);

  // Get profile information from payload
  String email = payload.getEmail();
  boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
  String name = (String) payload.get("name");
  String pictureUrl = (String) payload.get("picture");
  String locale = (String) payload.get("locale");
  String familyName = (String) payload.get("family_name");
  String givenName = (String) payload.get("given_name");

  // Use or store profile information
  // ...

} else {
  System.out.println("Invalid ID token.");
}

GoogleIdTokenVerifier.verify() 方法验证 JWT 签名、aud 声明、iss 声明以及 exp 项版权主张。

如果您需要验证 ID 令牌是否代表 Google Workspace 或 Cloud 组织账号,您可以通过检查域名来验证 hd 所有权声明 由 Payload.getHostedDomain() 方法返回。该 email 声明不足以保证账号是由网域管理 或组织。

。 <ph type="x-smartling-placeholder">
</ph>
Node.js

要在 Node.js 中验证 ID 令牌,请使用适用于 Node.js 的 Google Auth 库。 安装该库:

npm install google-auth-library --save
然后,调用 verifyIdToken() 函数。例如:

const {OAuth2Client} = require('google-auth-library');
const client = new OAuth2Client();
async function verify() {
  const ticket = await client.verifyIdToken({
      idToken: token,
      audience: CLIENT_ID,  // Specify the CLIENT_ID of the app that accesses the backend
      // Or, if multiple clients access the backend:
      //[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]
  });
  const payload = ticket.getPayload();
  const userid = payload['sub'];
  // If the request specified a Google Workspace domain:
  // const domain = payload['hd'];
}
verify().catch(console.error);

verifyIdToken 函数用于验证 JWT 签名、aud 声明、exp 声明 以及 iss 声明。

如果您需要验证 ID 令牌是否代表 Google Workspace 或 Cloud 组织账号时,您可以查看 hd 声明,该声明表示托管的 用户的网域。将资源访问权限限制为仅允许成员访问时,必须使用此设置 特定网域的用户缺少此声明即表示该账号不属于 Google 托管的域。

。 <ph type="x-smartling-placeholder">
</ph>
PHP

要在 PHP 中验证 ID 令牌,请使用适用于 PHP 的 Google API 客户端库。 安装该库(例如,使用 Composer):

composer require google/apiclient
然后,调用 verifyIdToken() 函数。例如:

require_once 'vendor/autoload.php';

// Get $id_token via HTTPS POST.

$client = new Google_Client(['client_id' => $CLIENT_ID]);  // Specify the CLIENT_ID of the app that accesses the backend
$payload = $client->verifyIdToken($id_token);
if ($payload) {
  $userid = $payload['sub'];
  // If the request specified a Google Workspace domain
  //$domain = $payload['hd'];
} else {
  // Invalid ID token
}

verifyIdToken 函数用于验证 JWT 签名、aud 声明、exp 声明 以及 iss 声明。

如果您需要验证 ID 令牌是否代表 Google Workspace 或 Cloud 组织账号时,您可以查看 hd 声明,该声明表示托管的 用户的网域。将资源访问权限限制为仅允许成员访问时,必须使用此设置 特定网域的用户缺少此声明即表示该账号不属于 Google 托管的域。

。 <ph type="x-smartling-placeholder">
</ph>
Python

要在 Python 中验证 ID 令牌,请使用 verify_oauth2_token 函数。例如:

from google.oauth2 import id_token
from google.auth.transport import requests

# (Receive token by HTTPS POST)
# ...

try:
    # Specify the CLIENT_ID of the app that accesses the backend:
    idinfo = id_token.verify_oauth2_token(token, requests.Request(), CLIENT_ID)

    # Or, if multiple clients access the backend server:
    # idinfo = id_token.verify_oauth2_token(token, requests.Request())
    # if idinfo['aud'] not in [CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]:
    #     raise ValueError('Could not verify audience.')

    # If the request specified a Google Workspace domain
    # if idinfo['hd'] != DOMAIN_NAME:
    #     raise ValueError('Wrong domain name.')

    # ID token is valid. Get the user's Google Account ID from the decoded token.
    userid = idinfo['sub']
except ValueError:
    # Invalid token
    pass

verify_oauth2_token 函数验证 JWT 签名、aud 声明和 exp 声明。 您还必须验证 hd 检查 verify_oauth2_token 返回。如果多个客户端访问 后端服务器,另请手动验证 aud 声明。

调用 tokeninfo 端点

调试验证 ID 令牌签名的一种简单方法是 使用 tokeninfo 端点。调用此端点涉及 这个额外的网络请求会为您完成大部分的验证工作, 验证和载荷提取。不适合在生产环境中使用 因为请求可能会受到限制或出现间歇性错误。

如需使用 tokeninfo 端点验证 ID 令牌,请创建 HTTPS POST 或 GET 请求发送到端点,并在 id_token 参数。 例如,要验证令牌“XYZ123”,请发出以下 GET 请求:

https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123

如果令牌经过正确签名,并且 issexp 具有预期值,就会收到 HTTP 200 响应,其中正文 包含 JSON 格式的 ID 令牌声明。 以下是示例响应:

{
 // These six fields are included in all Google ID Tokens.
 "iss": "https://accounts.google.com",
 "sub": "110169484474386276334",
 "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "iat": "1433978353",
 "exp": "1433981953",

 // These seven fields are only included when the user has granted the "profile" and
 // "email" OAuth scopes to the application.
 "email": "testuser@gmail.com",
 "email_verified": "true",
 "name" : "Test User",
 "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg",
 "given_name": "Test",
 "family_name": "User",
 "locale": "en"
}

如果您需要验证 ID 令牌是否代表 Google Workspace 账号,可以先查看 hd 声明,指示用户的托管网域。只有在以下情况下, 从而仅允许特定网域中的成员访问资源。缺少此声明 表示该账号不属于 Google Workspace 托管网域。

アカウントまたはセッションを作成する

トークンを確認したら、ユーザーがすでにユーザーに含まれているかどうかを確認する データベースですその場合は、ユーザーの認証済みセッションを確立します。ユーザーが まだユーザー データベースにない場合は、情報から新しいユーザー レコードを作成します。 を ID トークン ペイロード内で指定し、ユーザーのセッションを確立します。このプロンプトを 追加のプロファイル情報をユーザーに送信するには、 ユーザーを追加します。

ユーザーの安全をクロスアカウント保護機能が有効なアカウント

ユーザーのログインを Google に任せると、自動的に ユーザーのデータを保護するために Google が構築したセキュリティ機能とインフラストラクチャです。ただし、 万一、ユーザーの Google アカウントが不正使用された場合や、 重大なセキュリティ イベントが発生した場合、アプリは攻撃に対して脆弱になる可能性もあります。お客様のデータを 使用する必要がある場合は、クロスアカウントを使用して 保護: Google からセキュリティ通知を受け取れます。これらのイベントを受信すると、 ユーザーの Google アカウントのセキュリティに関する重要な変更に対する可視性を得る。 アカウントを保護するための措置を講じることができます。