如何在后端验证通过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
相关产品推荐
相关产品推荐

