Flutter Amplify中fetchAuthSession无法获取API Gateway认证有效令牌
Flutter Amplify 集成 Cognito 用户池授权调用 API Gateway 未授权问题解决
核心问题场景
已完成Flutter + Amplify的Cognito注册/登录功能,API Gateway使用AWS_IAM、API_KEY授权可正常调用Lambda,但切换为AMAZON_COGNITO_USER_POOLS授权时返回{"message":"Unauthorized"},需要通过该授权在Lambda中获取登录用户信息。
问题排查与解决步骤
1. 先确认API Gateway的Cognito授权器配置
- 检查API Gateway中创建的Cognito用户池授权器,是否关联了正确的用户池ID和客户端ID(需与Amplify配置中使用的Cognito客户端一致)
- 确认授权器的Token来源设置为
Authorization,且开启了令牌验证 - 确保目标API资源的授权方式已设置为
AMAZON_COGNITO_USER_POOLS,而非其他类型
2. 正确使用Amplify API调用(无需手动添加令牌)
当amplifyconfiguration.dart中已指定authorizationType: "AMAZON_COGNITO_USER_POOLS"时,Amplify会自动从已登录的会话中获取并注入正确的令牌到请求头,手动添加Authorization头反而可能导致冲突。修正后的调用代码如下:
// 先确认用户已登录 final session = await Amplify.Auth.fetchAuthSession(); if (session is CognitoAuthSession && session.isSignedIn) { var requestObject = {}; var encodedRequestObject = jsonEncode(requestObject); RestOptions options = RestOptions( path: '/api-path', apiName: 'lambdaapiplugin', body: Uint8List.fromList(encodedRequestObject.codeUnits), ); RestOperation restOperation = Amplify.API.post(restOptions: options); RestResponse response = await restOperation.response; // 处理响应逻辑 }
3. 手动获取令牌的正确姿势(如需自定义场景)
如果确实需要手动提取令牌,需注意:
- API Gateway的Cognito授权器默认验证的是ID Token,需确保传递的令牌格式正确
- 令牌必须携带
Bearer前缀(这是最容易忽略的错误),正确的请求头格式为:Authorization: Bearer {idToken} - 正确提取令牌的代码:
final session = await Amplify.Auth.fetchAuthSession(); if (session is CognitoAuthSession && session.isSignedIn) { final tokens = session.userPoolTokens!; // 使用ID Token,需添加Bearer前缀 final authHeader = 'Bearer ${tokens.idToken}'; }
4. Postman测试的正确流程
在Postman中测试时,需避免手动拼接令牌:
- 切换到
Authorization标签,选择OAuth 2.0类型 - 配置令牌获取参数:
- Token URL:Cognito用户池的Token端点(格式:
https://{你的用户池域名}/oauth2/token) - Grant Type:选择
Password(适配用户名密码登录流程) - Client ID:填入Cognito用户池的客户端ID
- Username/Password:测试用户的账号密码
- Scope:按需填写(如
openid用于获取ID Token)
- Token URL:Cognito用户池的Token端点(格式:
- 点击
Get New Access Token,获取到令牌后自动注入请求头,再发起请求
5. Lambda中获取用户信息的方式
授权成功后,API Gateway会将用户的Cognito声明自动注入Lambda的event参数中,直接读取即可:
// Node.js Lambda示例 exports.handler = async (event) => { // 获取用户信息 const userClaims = event.requestContext.authorizer.claims; const userId = userClaims.sub; const userEmail = userClaims.email; // 业务逻辑 return { statusCode: 200, body: JSON.stringify({ userId, userEmail }) }; };
常见错误总结
- 手动添加
Authorization头覆盖了Amplify的自动处理 - 令牌未添加
Bearer前缀,导致API Gateway无法识别 - API Gateway授权器与Cognito用户池/客户端ID不匹配
- 令牌已过期或验证失败(可通过jwt.io解析令牌检查
exp、iss、aud字段)
内容的提问来源于stack exchange,提问作者Kailas J C
相关产品推荐
相关产品推荐

