백엔드 서버와 통신하는 앱 또는 사이트에서 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 토큰을 수신한 후에는 토큰의 무결성을 확인해야 합니다.
토큰이 유효한지 확인하려면 다음을 확인하세요. 다음 기준을 충족해야 합니다.
- Google에서 ID 토큰을 올바르게 서명했는지 확인합니다. 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
클레임을 확인하면 사용자 도메인입니다. 리소스에 대한 액세스 권한을 특정 도메인을 사용하는 경우가 많습니다 이 소유권 주장이 없으면 계정이 다음에 속하지 않음을 나타냅니다. Google이 호스팅하는 도메인입니다.
email
, email_verified
, hd
필드를 사용하면
Google은 이메일 주소를 호스팅하고 이에 대한 권한이 있습니다. Google이 공신력 있는 경우
합법적인 계정 소유자로 알려진 경우 비밀번호나 기타 로그인 정보를 건너뛸 수
챌린지 방법.
Google이 신뢰할 수 있는 케이스:
email
의 접미사는@gmail.com
입니다. 이 계정은 Gmail 계정입니다.email_verified
이(가) true이고hd
이(가) 설정되어 있습니다. 이는 G Suite 계정입니다.
사용자는 Gmail 또는 G Suite를 사용하지 않고도 Google 계정에 등록할 수 있습니다. 날짜
email
에 @gmail.com
서픽스가 포함되어 있지 않고 hd
가 없는 경우 Google은 포함되지 않음
신뢰할 수 있는 비밀번호나 다른 본인 확인 방법을 사용하여
있습니다. Google에서 처음에 확인했으므로 email_verified
도 true일 수 있습니다.
사용자에게 양도할 수 있지만 제3자의 소유권은
이메일 계정이 변경되었을 수 있습니다.
이러한 확인 단계를 수행하기 위해 직접 코드를 작성하는 대신 Google에서는
플랫폼에 Google API 클라이언트 라이브러리를 사용하거나
JWT 라이브러리도 있습니다. 개발 및 디버깅을 위해 tokeninfo
를 호출할 수 있습니다.
엔드포인트가 있습니다
使用 Google API 客户端库
在生产环境中验证 Google ID 令牌时,建议使用一个 Google API 客户端库(例如 Java、Node.js、PHP、Python)。
要在 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 组织帐号,则可以通过检查 Payload.getHostedDomain()
方法返回的域名来验证 hd
声明。email
声明的网域不足以确保帐号由网域或组织管理。
如需在 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 托管的网域。
如需在 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 托管的网域。
要在 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
声明。您还必须通过检查 verify_oauth2_token
返回的对象来验证 hd
声明(如果适用)。如果多个客户端访问后端服务器,则还需要手动验证 aud
声明。
tokeninfo 엔드포인트 호출
디버깅을 위해 ID 토큰 서명의 유효성을 검사하는 쉬운 방법은 tokeninfo
엔드포인트를 사용하는 것입니다. 이 엔드포인트를 호출하려면 개발자가 자체 코드에서 적절한 유효성 검사 및 페이로드 추출을 테스트하는 동안 대부분의 유효성 검사를 수행하는 추가 네트워크 요청이 필요합니다. 요청이 제한되거나 간헐적인 오류가 발생할 수 있으므로 프로덕션 코드에서는 사용하지 않습니다.
tokeninfo
엔드포인트를 사용하여 ID 토큰의 유효성을 검사하려면 엔드포인트에 HTTPS POST 또는 GET 요청을 실행하고 id_token
매개변수에 ID 토큰을 전달합니다.
예를 들어 'XYZ123' 토큰을 검증하려면 다음 GET 요청을 수행합니다.
https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123
토큰이 올바르게 서명되고 iss
및 exp
클레임에 예상된 값이 있으면 본문에 JSON 형식의 ID 토큰 클레임이 포함된 HTTP 200 응답이 표시됩니다.
응답 예시는 다음과 같습니다.
{ // 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 계정 보안에 대한 중요 변경사항을 파악할 수 있으므로 서비스에서 계정을 보호하기 위한 조치를 취할 수 있습니다.