You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在后端验证通过AWS Amplify&Cognito登录的用户?

问题解答

1. 后端身份验证方向完全正确

你采用Cognito令牌传递到Flask后端做身份校验的思路,是AWS生态里前后端身份验证的标准实践,方向没有问题。

2. 获取完整JWT的方法

AWS Amplify的fetchAuthSession其实能返回完整的JWT(包含header、payload、signature),你应该是仅提取了令牌对象的payload属性才导致只拿到部分内容。正确操作如下:

前端获取完整令牌

调用fetchAuthSession后,直接调用令牌对象的toString()方法,即可拿到完整的JWT字符串,而不是只取payload:

import { fetchAuthSession } from 'aws-amplify/auth';

const getFullTokens = async () => {
  const session = await fetchAuthSession();
  // 获取完整身份令牌(格式:header.payload.signature)
  const fullIdToken = session.idToken?.toString();
  // 获取完整访问令牌
  const fullAccessToken = session.accessToken?.toString();
  // 发送到后端时,建议放在请求头的Authorization字段,格式为 Bearer {完整令牌}
  return { fullIdToken, fullAccessToken };
};

Amplify返回的CognitoIdToken/CognitoAccessToken对象本身包含完整的JWT串,payload只是其预解析后的属性,调用toString()就能拿到完整令牌。

后端验证完整JWT

在Flask端使用pyjwt验证时,先从请求头提取完整JWT,再结合Cognito的公钥池做校验(公钥可自动从Cognito的标准端点拉取,无需手动下载):

import jwt
import requests
from flask import request, jsonify

# 拉取Cognito的JWKS公钥池
def get_cognito_public_keys(user_pool_id, region):
    jwks_url = f"https://cognito-idp.{region}.amazonaws.com/{user_pool_id}/.well-known/jwks.json"
    response = requests.get(jwks_url)
    return response.json()["keys"]

# 验证Cognito令牌
def verify_cognito_token(token, user_pool_id, region, app_client_id):
    keys = get_cognito_public_keys(user_pool_id, region)
    try:
        # 自动匹配对应公钥完成解析与验证
        decoded = jwt.decode(
            token,
            keys,
            algorithms=["RS256"],
            audience=app_client_id,
            issuer=f"https://cognito-idp.{region}.amazonaws.com/{user_pool_id}"
        )
        return decoded
    except jwt.InvalidTokenError:
        return None

# Flask保护路由示例
@app.route('/protected', methods=['GET'])
def protected_route():
    auth_header = request.headers.get('Authorization')
    if not auth_header or not auth_header.startswith('Bearer '):
        return jsonify({"error": "无效的授权头"}), 401
    
    token = auth_header.split(' ')[1]
    # 替换为你的实际配置
    user_pool_id = "你的Cognito用户池ID"
    region = "你的AWS区域"
    app_client_id = "你的Cognito应用客户端ID"
    
    decoded_token = verify_cognito_token(token, user_pool_id, region, app_client_id)
    if not decoded_token:
        return jsonify({"error": "令牌无效或已过期"}), 403
    
    return jsonify({"message": "身份验证通过", "用户ID": decoded_token["sub"]})

额外提示

  • 优先用**访问令牌(access token)**做API校验,身份令牌(identity token)更适合前端展示用户信息,访问令牌的权限控制更贴合API场景。
  • 验证时必须指定audience(应用客户端ID)和issuer(Cognito用户池端点),防止令牌被非法复用。
  • 可以缓存Cognito的JWKS公钥,不用每次校验都拉取,提升后端性能。

内容的提问来源于stack exchange,提问作者David Cian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 11:47:11