Amazon Cognito
开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 Amazon AWS 入门

验证 JSON Web 令牌

这些步骤描述了验证用户池 JSON Web 令牌 (JWT) 的过程。

先决条件

  • 本部分介绍可能已由您的库、开发工具包或软件框架进行处理的任务。例如,用户池令牌处理和管理在客户端上是通过 Amazon Cognito 开发工具包提供的。同样,如果存在有效的(非过期的)刷新令牌,Mobile SDK for iOS 和 适用于 Android 的 移动软件开发工具包 会自动刷新您的 ID 令牌和访问令牌,而且 ID 令牌和访问令牌至少有 5 分钟的剩余有效性。有关开发工具包以及适用于 JavaScript、Android 和 iOS 的示例代码,请参阅 Amazon Cognito 用户池开发工具包

  • 如果您需要手动处理用于服务器 API 处理的令牌,或者您使用的是其他编程语言,则有很多用于解码和验证 JWT 的好库。请参阅用于处理 JWT 令牌的库的 OpenID Foundation 列表

步骤 1:确认 JWT 的结构

一个 JSON Web 令牌 (JWT) 包含三个部分:

  1. 标头

  2. Payload

  3. 签名

11111111111.22222222222.33333333333

它们以 Base64url 字符串的格式编码,并且用点“.”characters. 如果您的 JWT 不符合此结构,请将其视为无效,且不得接受它。

步骤 2:验证 JWT 签名

JWT 签名是标头和负载的哈希组合。Amazon Cognito 为每个用户池生成两对 RSA 加密密钥。其中一对私有密钥用于对令牌进行签名。

验证 JWT 令牌的签名

  1. 解码 ID 令牌。

    1. 您可以使用 AWS Lambda 解码用户池 JWT。有关更多信息,请参阅使用 Lambda 解码并验证 Amazon Cognito JWT 令牌

    2. OpenID Foundation 还维护用于处理 JWT 令牌的库列表

  2. 将本地密钥 ID (kid) 比作公有 kid。

    1. 下载并存储适用于用户池的对应的公有 JSON Web Key (JWK)。它可作为 JSON Web Key Set (JWKS) 的一部分提供。您可以在 https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json 找到它。

      有关更多 JWK 和 JWK 集的更多信息,请参阅 JSON Web Key (JWK)

      注意

      先完成这个一次性步骤,然后您的 Web API 才可以处理令牌。现在,每当 ID 令牌或访问令牌用于您的 Web API 时,您都可以执行以下步骤。

      这是一个示例 jwks.json 文件:

      { "keys": [{ "kid": "1234example=", "alg": "RS256", "kty": "RSA", "e": "AQAB", "n": "1234567890", "use": "sig" }, { "kid": "5678example=", "alg": "RS256", "kty": "RSA", "e": "AQAB", "n": "987654321", "use": "sig" }] }
      密钥 ID (kid)

      kid 是一个提示,指示哪些密钥用于保护令牌的 JSON Web Signature (JWS)。

      算法 (alg)

      alg 标头参数表示用于保护 ID 令牌的加密算法。用户池使用 RS256 加密算法,这是一种采用 SHA-256 的 RSA 签名。有关 RSA 的更多信息,请参阅 RSA 密码术

      密钥类型 (kty)

      kty 参数标识与密钥结合使用的加密算法系列,例如,在本示例中为“RSA”。

      RSA 指数 (e)

      e 参数包含 RSA 公有密钥的指数值。它表示为采用 Base64urlUInt 编码的值。

      RSA 模数 (n)

      n 参数包含 RSA 公有密钥的模数值。它表示为采用 Base64urlUInt 编码的值。

      使用 (use)

      use 参数描述了公有密钥的预期用途。在本示例中,use 值 sig 表示签名。

    2. 搜索与您的 JWT 的 kid 相匹配的 kid 的公有 JSON Web Key。

  3. 使用公有密钥来利用您的 JWT 库验证签名。您可能首先需要将 JWK 转换为 PEM 格式。本示例采用 JWT 和 JWK 格式,并且使用 Node.js 库、jsonwebtoken,来验证 JWT 签名:

    Node.js
    Node.js
    var jwt = require('jsonwebtoken'); var jwkToPem = require('jwk-to-pem'); var pem = jwkToPem(jwk); jwt.verify(token, pem, { algorithms: ['RS256'] }, function(err, decodedToken) { });

步骤 3:验证声明

验证 JWT 声明

  1. 确认该令牌没有过期。

  2. 受众 (aud) 声明应与在 Amazon Cognito 用户池中创建的应用程序客户端 ID 匹配。

  3. 发布者 (iss) 声明应与您的用户池匹配。例如,在 us-east-1 区域中创建的用户池的 iss 值为:

    https://cognito-idp.us-east-1.amazonaws.com/<userpoolID>

  4. 检查 token_use 声明。

    • 如果您在 Web API 中只接受访问令牌,则其值必须为 access

    • 如果您只使用 ID 令牌,则其值必须为 id

    • 如果您同时使用 ID 令牌和访问令牌,则 token_use 声明必须为 idaccess

您现在可以信任该令牌内的声明。