如何验证AWS Cognito Amplify各类Token及吊销后refreshToken有效性
Cognito没有提供统一的全类型Token校验接口,不同Token的校验逻辑差异很大,以下是可直接落地的实现方式,包含你需要的Refresh Token吊销后有效性验证逻辑:
1. Refresh Token 校验(含吊销后状态判断)
你当前调用的revoke_token是Cognito官方的Refresh Token吊销接口,吊销后的Token会进入Cognito内置的黑名单,直到其自然过期才会被清除。注意不要靠本地解码JWT的方式校验Refresh Token有效性:Refresh Token虽然是JWT格式,但吊销状态不会写入Token载荷,本地验签完全识别不出已吊销的Token。
正确的校验方式是直接调用Cognito的刷新令牌鉴权接口做试探性请求:
- 传入待校验的Refresh Token,调用
initiate_auth接口指定REFRESH_TOKEN_AUTH鉴权流 - 结果判断规则:
- 接口返回
NotAuthorizedException,提示Refresh Token无效/已吊销,说明Token已失效 - 接口正常返回新的Access Token、ID Token,说明该Refresh Token仍处于有效状态
- 接口返回
对应校验代码参考:
def is_refresh_token_valid(refresh_token: str, client_id: str) -> bool: cognito_client = boto3.client('cognito-idp') try: cognito_client.initiate_auth( ClientId=client_id, AuthFlow='REFRESH_TOKEN_AUTH', AuthParameters={ 'REFRESH_TOKEN': refresh_token } ) return True except cognito_client.exceptions.NotAuthorizedException: return False # 参数错误、客户端权限错误等其他异常单独抛出,不要和Token失效逻辑混淆
注意:默认配置下,吊销Refresh Token不会让之前用它签发的未过期Access Token、ID Token自动失效——这两类是无状态JWT,Cognito不会主动回收,除非你主动开启用户池的Token全链路吊销功能。
2. Access Token 校验
Access Token是标准签名JWT,校验分两个层级,根据业务安全等级选择:
- 常规场景本地校验(无API调用,性能高):
- 获取对应用户池的公开JWKS签名公钥
- 验证JWT签名合法性
- 校验载荷核心字段:
exp过期时间未到iss签发者和当前用户池匹配token_use值为accessclient_id和你的应用客户端ID一致
- 高安全等级强校验:
- 携带待校验的Access Token调用
get_user接口,接口正常返回用户属性则Token有效,返回NotAuthorizedException则Token已失效 - 这种方式可以识别出用户被删除、Token被全局吊销等本地校验无法感知的状态,但会增加API调用开销,生产环境不要在每次接口请求时都调用,容易触发Cognito限流。
- 携带待校验的Access Token调用
3. ID Token 校验
ID Token同样是签名JWT,基础校验逻辑和Access Token一致,差异点在于:
- 本地校验时需确认
token_use字段值为id,如果登录流程中传递了nonce参数,还要额外校验载荷里的nonce和发起登录时生成的随机值一致,避免重放攻击 - ID Token本身仅用于客户端侧的用户身份标识,不能用来调用Cognito的鉴权接口,需要做用户状态强校验时,可以先完成本地验签,再提取载荷里的
sub(用户唯一ID)调用admin_get_user接口查询用户当前状态。
实用提示:如果需要吊销Refresh Token后让其签发的所有Access、ID Token立刻失效,需要在Cognito用户池配置中开启Token吊销功能。开启后Cognito会记录每个Refresh Token的签发链路,吊销父级Refresh Token后,其签发的所有未过期短周期Token在调用Cognito鉴权接口时都会被直接拒绝。
内容的提问来源于stack exchange,提问作者ambigus9

