Help us improve the AWS re:Post Knowledge Center by sharing your feedback in a brief survey. Your input can influence how we create and update our content to better support your AWS journey.
如何解码和验证 Amazon Cognito JSON Web 令牌的签名?
我想使用 Amazon Cognito 用户池作为我的应用程序的身份验证方法。我想要一种安全的方法来验证客户发送到我的应用程序的 ID 令牌和访问令牌。
简短描述
当客户端使用用户池对您的应用程序进行身份验证时,Cognito 会发送 JSON Web 令牌 (JWT) 供您解码、读取和修改。要从 JWT 获取 Cognito 用户详细信息,请解码令牌并验证签名。
**重要事项:**在授予资源访问权限之前,必须验证签名。
解决方法
验证 Cognito 是否发布了 JWT
在 JavaScript 中使用以下代码:
import { CognitoJwtVerifier } from "aws-jwt-verify"; // Verifier that expects valid access tokens: const verifier = CognitoJwtVerifier.create({ userPoolId: "user_pool_id", tokenUse: "access", clientId: "client_id", }); try { const payload = await verifier.verify( "eyJraWQeyJhdF9oYXNoIjoidk..." // the JWT as string ); console.log("Token is valid. Payload:", payload); } catch { console.log("Token not valid!"); }
**注意:**将 user_pool_id 替换为您的用户池 ID,将 client_id 替换为您的应用程序客户端 ID。对于 ID 令牌,将 tokenUse 字段更新为 "id"。有关可用参数的列表,请参阅 GitHub 网站上的 aws-jwt-verify。
如果您使用其他编程语言,请查看 JWT 网站上的 jwt.io 库或 OpenID 网站上的 OpenID Connect 库。有关代码示例,请参阅 GitHub 网站上的解码和验证 Amazon Cognito JWT 令牌。
Cognito 最多返回三个令牌:ID 令牌、访问令牌和刷新令牌。如果您使用 REST API、AWS Amplify 或 AWS SDK 对用户进行身份验证,则您将获得所有三个令牌。
对于 Cognito 托管式用户界面,您获得的令牌取决于您使用的授权授予类型。如果您使用隐式授予,则只能获得访问令牌和 ID 令牌。授权码授予会返回访问令牌、ID 令牌和刷新令牌。客户端凭证授予仅返回访问令牌。
访问令牌和 ID 令牌包括标头、有效载荷和签名。客户端无法解码或验证刷新令牌。
以下是 ID 令牌标头的示例。标头包含密钥 ID ("kid")和用于签署令牌的算法 ("alg")。RS256 算法是使用 SHA-256 的 RSA 签名:
{ "kid": "key_id_example=", "alg": "RS256" }
以下是包含用户信息以及令牌创建和到期时间戳的有效载荷示例:
{ "sub": "aaaaaaaa-bbbb-cccc-dddd-example", "aud": "audience_example", "email_verified": true, "token_use": "id", "auth_time": 1500009400, "iss": "https://cognito-idp.ap-southeast-2.amazonaws.com/ap-southeast-2_example", "cognito:username": "anaya", "exp": 1500013000, "given_name": "Anaya", "iat": 1500009400, "email": "anaya@example.com" }
签名是标头和有效载荷的哈希和加密组合。
Cognito 为每个用户池生成两个 RSA 密钥对。每对的私钥用于对 ID 令牌或访问令牌进行加密签名。您可以在以下位置找到公钥:
https://cognito-idp.region.amazonaws.com/userPoolId/.well-known/jwks.json
**注意:**将 region 替换为您的用户池所在的 AWS 区域,将 userPoolId 替换为您的用户池 ID。
JSON 文件 (jwks.json) 的结构采用如下格式:
{ "keys": [{ "alg": "RS256", "e": "AQAB", "kid": "abcdefghijklmnopqrsexample=", "kty": "RSA", "n": "lsjhglskjhgslkjgh43lj5h34lkjh34lkjht3example", "use": "sig" }, { "alg": "RS256", "e": "AQAB", "kid": "fgjhlkhjlkhexample=", "kty": "RSA", "n": "sgjhlk6jp98ugp98up34hpexample", "use": "sig" }] }
要验证 Cognito JWT 的签名,请使用与令牌标头匹配的密钥 ID 搜索公钥。使用不同的库来验证令牌的签名并提取值,例如到期日和用户名。
最佳实践是验证令牌未过期。此外,请确保有效载荷中的受众 ("aud") 与您在 Amazon Cognito 用户池中创建的应用程序客户端 ID 相匹配。aws-jwt-verify 库会为您检查这些值。有关更多信息,请参阅 GitHub 网站上的 aws-jwt-verify。
缓存公钥
由于 JWKS 端点中的公钥很少轮换,因此您无需在每次验证令牌时都从端点下载它们。取而代之的是,下载公钥并将其缓存到使用 JWT 令牌验证逻辑的本地计算机上。
"kid" 是公钥的唯一标识符。要验证 JWT 令牌,请检查您的本地缓存以确定令牌标头中的 "kid" 是否在缓存中。如果没有缓存,则从 JWKS 端点下载公钥并更新您的缓存。
使用不同的方法检查令牌的到期或撤销状态
您可以撤消刷新令牌并使访问令牌失效,但不能撤销 ID 令牌。JWT 验证器库会验证令牌的到期时间,但这些库不会检查令牌的撤销状态。撤销状态的检查需要通过服务器端进行检查。
相关信息
- 语言
- 中文 (简体)

相关内容
AWS 官方已更新 6 个月前