调用Paws::CognitoIdp::GetUser返回Invalid Access Token问题求助
解决方案
核心误区澄清
你打印出的$cognito_idp对象中credentials字段下的Token是EC2实例的IAM角色凭证,用于Paws调用AWS服务的接口鉴权,和Cognito用户身份的AccessToken完全无关,不能直接用作GetUser接口的参数。
AccessToken的获取方式
你通过Google OAuth登录Cognito走的是OAuth2.0授权码流,AccessToken需要从Cognito的令牌接口换取,步骤如下:
- 获取授权码:用户点击Google登录完成后,Cognito会向你配置的回调地址发起请求,URL参数中的
code就是授权码,你可以在CGI脚本中通过查询参数拿到这个值。 - 换取Cognito用户令牌:用授权码调用Cognito用户池的OAuth2令牌接口,即可获得包括AccessToken在内的用户凭证。
- 调用GetUser接口:将上一步拿到的
access_token字段值作为AccessToken参数传入即可。
完整代码示例
use strict; use warnings; use LWP::UserAgent; use JSON; use Paws; use CGI; my $cgi = CGI->new; # 1. 从回调请求中拿到授权码 my $auth_code = $cgi->param('code'); # 2. 配置Cognito参数,替换为你自己的实际值 my $cognito_domain = '你的用户池域名.auth.ap-northeast-1.amazoncognito.com'; my $client_id = '你的Cognito应用客户端ID'; my $redirect_uri = '你配置的回调地址,和控制台完全一致'; # 调用令牌接口换取AccessToken my $ua = LWP::UserAgent->new; my $token_response = $ua->post( "https://$cognito_domain/oauth2/token", Content_Type => 'application/x-www-form-urlencoded', Content => [ grant_type => 'authorization_code', client_id => $client_id, redirect_uri => $redirect_uri, code => $auth_code, # 如果你的应用客户端勾选了「生成客户端密钥」,还要加下面一行 # client_secret => '你的客户端密钥' ] ); die "令牌请求失败: ".$token_response->status_line unless $token_response->is_success; my $token_data = decode_json($token_response->decoded_content); my $access_token = $token_data->{access_token}; # 3. 调用GetUser接口获取用户信息 my $cognito_idp = Paws->service('CognitoIdp', region => 'ap-northeast-1', max_attempts => 3, ); my $user_response = $cognito_idp->GetUser(AccessToken => $access_token); # 提取用户名和邮箱 my $username = $user_response->Username; my $email; foreach my $attr (@{$user_response->UserAttributes}) { if ($attr->Name eq 'email') { $email = $attr->Value; last; } } # 测试打印 print "Content-type: text/html\n\n"; print "用户名: $username<br>邮箱: $email";
CLI调试方法
如果需要用AWS CLI验证,首先按上述方式拿到AccessToken后直接执行:
aws cognito-idp get-user --access-token <你拿到的AccessToken值> --region ap-northeast-1
即可返回完整的用户属性信息。
注意事项
- Cognito应用客户端必须开启「授权码流」权限,否则令牌接口会报错
- 回调地址必须和Cognito控制台配置的完全一致,包括协议、域名、路径、末尾斜杠都不能有差异
- AccessToken默认有效期1小时,过期后可以用令牌接口返回的
refresh_token调用刷新接口获取新的AccessToken
内容的提问来源于stack exchange,提问作者Chihiro Fukazawa
相关产品推荐
相关产品推荐

