如何在AWS JavaScript SDK v3中刷新凭证?——从V2迁移后解决凭证过期问题的方法咨询
我明白你在从AWS SDK v2迁移到v3时遇到的凭证刷新问题——确实v3的模块化设计和v2差异不小,原来的Credentials.refresh()方法没有直接对应的API,但我们可以通过两种方式实现同样的功能,解决你碰到的NotAuthorizedException(ID Token过期)问题:
方式一:手动刷新ID Token并重新获取身份凭证
这个方式和你当前的代码逻辑衔接最紧密,分两步走:
用Refresh Token获取新的有效ID Token
首先你需要通过Cognito用户池的认证接口,用用户保存的Refresh Token换取新的ID Token(前提是用户之前登录时获取到了有效的Refresh Token)。示例代码如下:import { CognitoIdentityProviderClient, InitiateAuthCommand } from "@aws-sdk/client-cognito-identity-provider"; const cognitoUserPoolClient = new CognitoIdentityProviderClient({ region: awsRegion }); // 构建刷新认证的参数 const refreshAuthParams = { AuthFlow: "REFRESH_TOKEN_AUTH", ClientId: "你的Cognito用户池客户端ID", // 替换为实际的客户端ID AuthParameters: { REFRESH_TOKEN: "用户保存的有效Refresh Token", // 如果你的用户池客户端设置了Secret,需要添加计算后的SECRET_HASH // SECRET_HASH: "根据用户名、客户端ID和Secret计算的哈希值" } }; // 发送请求获取新的认证凭证 const authResult = await cognitoUserPoolClient.send(new InitiateAuthCommand(refreshAuthParams)); const newIdToken = authResult.AuthenticationResult.IdToken;用新的ID Token重新调用GetIdCommand获取身份凭证
拿到新的ID Token后,直接替换你原有代码里的旧Token,重新执行GetIdCommand即可拿到有效的新凭证:credentials = await cognitoIdentity.send( new GetIdCommand({ Storage: config, IdentityPoolId: config.get("IdentityPoolId"), Logins: { [`cognito-idp.${awsRegion}.amazonaws.com/${upid}`]: newIdToken, }, }), );
方式二:使用官方凭证提供者自动管理刷新
AWS SDK v3提供了@aws-sdk/credential-provider-cognito-identity包,它可以自动帮你处理凭证的过期和刷新,不用手动调用GetIdCommand,代码更简洁:
先安装这个包(如果还没装的话):
npm install @aws-sdk/credential-provider-cognito-identity @aws-sdk/client-cognito-identity使用
fromCognitoIdentityPool创建凭证提供者:import { fromCognitoIdentityPool } from "@aws-sdk/credential-provider-cognito-identity"; import { CognitoIdentityClient } from "@aws-sdk/client-cognito-identity"; const cognitoIdentityClient = new CognitoIdentityClient({ region: awsRegion }); // 创建凭证提供者 const credentialsProvider = fromCognitoIdentityPool({ client: cognitoIdentityClient, identityPoolId: config.get("IdentityPoolId"), logins: { [`cognito-idp.${awsRegion}.amazonaws.com/${upid}`]: idToken, // 初始的ID Token }, }); // 当需要使用凭证时,直接调用提供者函数,它会自动处理刷新 const freshCredentials = await credentialsProvider();这里需要注意:如果你的ID Token过期了,这个提供者会尝试用当前
logins里的Token刷新身份凭证,但如果Token本身已经失效,你需要先更新logins里的ID Token(通过方式一的步骤获取新Token后,修改credentialsProvider配置里的logins),再调用提供者函数。
另外,建议在应用里封装一个工具函数,每次调用AWS服务前先解析ID Token的exp字段(JWT的过期时间戳),提前判断是否需要刷新,避免抛出过期异常。
内容的提问来源于stack exchange,提问作者comonadd




