Android端Google认证对接AWS Cognito身份池失败问题排查
我之前也碰到过一模一样的坑,折腾了大半天才找到问题所在,给你几个针对性的排查和解决方向:
1. 先确认Google令牌的「受众(Audience)」是否匹配
这是最常见的问题!GoogleSignInApi默认返回的令牌,受众可能是你的Android客户端ID,但Cognito身份池要求的是你配置的Google Web App Client ID。你可以解码令牌(用本地JWT工具就行),看aud字段是不是和身份池里填的Web Client ID完全一致。
如果不一致,那你得在获取令牌时指定正确的受众:在Android的GoogleSignInOptions里,一定要用requestIdToken("你的Web App Client ID"),而不是填Android的客户端ID。很多人在这里搞混,直接用了Android端的ID,导致令牌不被Cognito认可。
2. 确保你传的是ID Token,不是Access Token
GoogleSignInApi会返回多种令牌,Cognito的GetIdAsync()只认ID Token(包含用户身份信息的JWT格式令牌),而不是用来调用Google API的Access Token。你可以检查令牌内容:ID Token里会有sub(用户唯一ID)、email这类身份字段,而Access Token主要是权限相关的内容。
3. 再仔细核对身份池的Google配置
虽然你说Client ID一致,但再抠细节检查一遍:
- AWS身份池的「身份验证提供商」里,Google是不是处于启用状态;
- 配置的提供商类型是不是选的「Google」(不是旧的Google+选项);
- 「客户端ID」字段有没有多余空格、大小写错误,确保和Google Cloud控制台里的Web App Client ID完全一致。
4. 验证令牌的有效性和过期时间
解码令牌看看exp字段(过期时间戳),确认令牌还在有效期内。如果过期了,重新获取一个新令牌再试。
另外,你可以用AWS CLI手动测试一下,比如执行这条命令(替换成你的参数):
aws cognito-identity get-id --identity-pool-id "你的身份池ID" --logins "accounts.google.com=你的Google ID Token"
如果CLI能成功返回身份ID,那问题大概率出在你的代码传递令牌的环节;如果CLI也报错,那就是令牌或者身份池配置的问题。
5. 对比两种获取令牌方式的差异
你提到用了两种方式获取Google令牌,那把两种方式返回的令牌解码后对比:
- 看
aud、iss字段是否一致; - 确认是不是都是ID Token;
- 比如其中一种用了
GoogleAuthUtil.getToken(),另一种用了GoogleSignInAccount.getIdToken(),前者的受众可能是Android客户端ID,后者可以指定Web App ID,这时候就要选后者的方式。
附:Android端正确获取Google ID Token的示例代码
// 构建GoogleSignInOptions时指定Web App Client ID GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken("你的Google Web App Client ID") .requestEmail() .build(); GoogleSignInClient signInClient = GoogleSignIn.getClient(this, gso); // 登录成功后获取ID Token Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data); try { GoogleSignInAccount account = task.getResult(ApiException.class); String validIdToken = account.getIdToken(); // 将validIdToken传给Cognito的GetIdAsync() } catch (ApiException e) { Log.e(TAG, "Google登录失败: " + e.getMessage()); }
要是这些方法都试过还是不行,可以把令牌解码后的aud、iss字段(敏感信息打码),还有身份池的配置截图贴出来,方便进一步排查。
内容的提问来源于stack exchange,提问作者mipnw

