如何从AWS Cognito托管UI重定向中获取注册用户信息?
问题解决思路
关于授权码(code)的作用与后续步骤
你看到的code=140ac1a7-aaaa-bbbb-cccc-180bcb7c55f0是Cognito返回的授权码(Authorization Code),属于OAuth 2.0的Authorization Code Flow流程——它本身不直接关联用户信息,需要后端用这个code去交换包含用户身份信息的ID Token和Access Token。你遗漏的核心步骤是后端完成授权码到Token的兑换流程,具体操作如下:
1. 确认Cognito客户端配置
- 登录AWS控制台进入Cognito用户池的客户端设置:
- 确保已勾选Authorization Code Grant授权类型
- 勾选需要的OAuth范围(如
openid、email、profile,至少要openid才能获取用户身份信息) - 确认你的重定向URI
https://example.com/signup已添加到「允许的回调URL」列表中
2. Java后端实现授权码兑换Token
使用AWS SDK for Java v2调用Cognito的Token端点,示例代码如下:
import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.cognitoidentityprovider.CognitoIdentityProviderClient; import software.amazon.awssdk.services.cognitoidentityprovider.model.InitiateAuthRequest; import software.amazon.awssdk.services.cognitoidentityprovider.model.InitiateAuthResponse; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; import java.util.HashMap; import java.util.Map; public class CognitoTokenExchange { public static void main(String[] args) { Region region = Region.US_EAST_1; // 替换为你的用户池所在区域 CognitoIdentityProviderClient cognitoClient = CognitoIdentityProviderClient.builder() .region(region) .build(); String clientId = "你的Cognito客户端ID"; String clientSecret = "你的Cognito客户端密钥(仅保密客户端需要)"; String authorizationCode = "重定向返回的code参数值"; String redirectUri = "https://example.com/signup"; Map<String, String> authParams = new HashMap<>(); authParams.put("CODE", authorizationCode); authParams.put("REDIRECT_URI", redirectUri); authParams.put("CLIENT_ID", clientId); if (clientSecret != null && !clientSecret.isEmpty()) { // 授权码兑换时用户名参数留空即可 authParams.put("SECRET_HASH", calculateSecretHash(clientId, clientSecret, "")); } InitiateAuthRequest authRequest = InitiateAuthRequest.builder() .clientId(clientId) .authFlow("AUTHORIZATION_CODE_AUTH") .authParameters(authParams) .build(); InitiateAuthResponse authResponse = cognitoClient.initiateAuth(authRequest); String idToken = authResponse.authenticationResult().idToken(); String accessToken = authResponse.authenticationResult().accessToken(); // 用JJWT等库解析ID Token(JWT格式)获取用户信息 // 示例:Claims claims = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(idToken).getBody(); // String userId = claims.getSubject(); // String email = claims.get("email", String.class); } // 计算SecretHash(仅当客户端有密钥时需要) private static String calculateSecretHash(String clientId, String clientSecret, String username) { try { Mac mac = Mac.getInstance("HmacSHA256"); SecretKeySpec secretKey = new SecretKeySpec(clientSecret.getBytes("UTF-8"), "HmacSHA256"); mac.init(secretKey); mac.update(clientId.getBytes("UTF-8")); mac.update(username.getBytes("UTF-8")); byte[] hash = mac.doFinal(); return Base64.getEncoder().encodeToString(hash); } catch (Exception e) { throw new RuntimeException("计算SecretHash失败", e); } } }
兑换成功后,你会得到ID Token(JWT格式),解析这个Token就能获取用户的身份信息(如用户ID、邮箱、用户名等)。
关于response_type=token的错误原因
你遇到的unauthorized_client&error=invalid_request错误,是因为Implicit Flow(response_type=token)的配置不符合要求,解决方法:
- 检查客户端类型:如果你的客户端设置了「Generate client secret」(即保密客户端),Implicit Flow是不被允许的。需要编辑Cognito客户端,取消勾选「Generate client secret」,改为公开客户端后重新配置OAuth设置。
- 确认授权类型:在客户端的OAuth设置中,勾选Implicit Grant授权类型。
- 验证重定向URI:确保
https://example.com/signup已在「允许的回调URL」列表中,且格式完全匹配(包括协议、路径)。
注意:Implicit Flow会直接在前端返回Token,安全性低于Authorization Code Flow,如果你用Java后端处理身份逻辑,更推荐使用Authorization Code Flow。
内容的提问来源于stack exchange,提问作者Qvery
相关产品推荐
相关产品推荐

