如何修复AWS SDK Java实现Cognito登录的Access key错误并适配SPA?
问题修复与方案说明
报错原因
你遇到的"Access key must be specified"错误,是因为AWS SDK for Java默认会尝试加载AWS访问密钥对请求进行签名,但Cognito用户池的USER_PASSWORD_AUTH认证流程,对于无客户端密钥的公开客户端(比如你的SPA应用),不需要AWS账号权限签名——这个流程是用户直接提交用户名密码到Cognito,和AWS账号的访问密钥无关。
本地Java代码修复
要让本地测试的Java代码正常运行,只需在创建Cognito客户端时指定使用匿名凭证,这样SDK就不会尝试加载访问密钥:
package org.acme; import java.util.Map; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.cognitoidentityprovider.CognitoIdentityProviderClient; import software.amazon.awssdk.services.cognitoidentityprovider.model.*; import software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider; public class App { public static void main(String[] args) { if (args.length != 1) { System.err.println("Usage: java App <password>"); System.exit(1); } Region region = Region.AP_NORTHEAST_1; String clientId = "1e18esapaevuqx9evrtcqmhntp"; String username = "user1"; String password = args[0]; // 创建客户端时指定匿名凭证,避免加载AWS访问密钥 CognitoIdentityProviderClient cognitoClient = CognitoIdentityProviderClient.builder() .region(region) .credentialsProvider(AnonymousCredentialsProvider.create()) .build(); InitiateAuthResponse initiateAuthResponse = cognitoClient.initiateAuth(InitiateAuthRequest.builder() .clientId(clientId) .authFlow(AuthFlowType.USER_PASSWORD_AUTH) .authParameters(Map.of("USERNAME", username, "PASSWORD", password)) .build()); AuthenticationResultType authenticationResult = initiateAuthResponse.authenticationResult(); System.out.println("Authentication successful"); System.out.println("Access Token: " + authenticationResult.accessToken()); System.out.println("ID Token: " + authenticationResult.idToken()); System.out.println("Refresh Token: " + authenticationResult.refreshToken()); System.out.println("Expires In: " + authenticationResult.expiresIn()); } }
SPA部署的标准方案
注意:AWS SDK for Java是后端服务端SDK,不能直接部署到浏览器端SPA应用中——浏览器环境无法安全处理Java依赖,且公开客户端(SPA)的认证流程应该用前端专用的方案:
推荐使用AWS Amplify JavaScript库:这是AWS官方为前端应用提供的工具库,集成了Cognito认证功能,只需简单配置即可实现用户登录、令牌管理等功能。示例代码(JavaScript):
import { Auth } from 'aws-amplify'; // 初始化Amplify(提前配置用户池和客户端ID) Amplify.configure({ Auth: { region: 'ap-northeast-1', userPoolId: '你的用户池ID', userPoolWebClientId: '1e18esapaevuqx9evrtcqmhntp' } }); // 用户登录 async function signIn(username, password) { try { const user = await Auth.signIn(username, password); console.log('登录成功', user.signInUserSession); // 获取令牌:user.signInUserSession.accessToken.jwtToken } catch (error) { console.log('登录失败', error); } }若不想依赖Amplify,也可以直接调用Cognito的REST API:向
https://cognito-idp.ap-northeast-1.amazonaws.com/发送POST请求,请求体包含认证参数,无需AWS签名。
内容的提问来源于stack exchange,提问作者loginWith loginWith
相关产品推荐
相关产品推荐

