Knowledge Center Monthly Newsletter - March 2025
Stay up to date with the latest from the Knowledge Center. See all new and updated Knowledge Center articles published in the last month and re:Post’s top contributors.
如何解码和验证 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 官方已更新 2 年前
- AWS 官方已更新 9 个月前
- AWS 官方已更新 1 年前
- AWS 官方已更新 2 年前