如何在 AWS amplify-js 中处理刷新令牌服务

tec*_*e18 8 amazon-web-services amazon-cognito aws-amplify

在我的反应项目中,我使用 AWS Cognito 用户池进行用户管理,对于用户身份验证,我使用 AWS Cognito idToken。90 分钟后会话将过期,然后我需要使用新的 idToken 刷新。如何使用 amplify-js 在 AWS Cognito 中处理刷新令牌服务。我试过Auth.currentSession()我会每 1 小时调用一次,但它对我不起作用。

小智 11

打电话Auth.currentSession()应该可以解决你的问题。Amplify-js 将刷新逻辑从您那里抽象出来。

在后台currentSession()获取CognitoUser对象,并调用其名为 的类方法getSession()。正是这种方法,它执行以下操作:

  1. 从您的存储中获取idToken、accessToken、refreshToken和clockDrift。
  2. 验证令牌(即 idToken 和 accessToken)以查看它们是否已过期。
  3. 如果令牌有效,则返回当前会话。
  4. 如果令牌已过期,则调用该类的refreshSession()方法,该方法CognitoUser与 AWS 身份提供商进行通信以生成一组新的令牌。

您现在要做的就是:

  1. 确保Auth.currentSession()定期打电话
  2. 始终调用Auth.currentSession()以获取您发出的每个 http 请求的令牌。

您可以使用这样的包装器:

const getAccessJwtToken = async () => {
  // Auth.currentSession() checks if token is expired and refreshes with Cognito if needed automatically
  const session = await Auth.currentSession();
  return session.getAccessToken().getJwtToken();
};
Run Code Online (Sandbox Code Playgroud)

最后,这个github讨论还介绍了一种非常好的手动刷新令牌的方法,并介绍了何时应该探索该选项的用例。

  • 我认为应该是 getIdToken() 因为 getAccessToken() 对我们不起作用。 (2认同)

tho*_*ace 7

只要会话处于活动状态(即用户正在进行 api 调用等),Amplify 就会自动保持会话新鲜。

如果您想强制会话保持活动状态,即使他们没有主动使用您的 API,那么最简单的方法就是Auth.currentAuthenticatedUser()定期调用。


tec*_*e18 7

经过长时间的努力,我找到了更新 AWS Cognito 刷新令牌的解决方案,为此我使用了 amazon-cognito-identity-js

const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
const CognitoUserPool = AmazonCognitoIdentity.CognitoUserPool;

componentWillReceiveProps(nextProps) {
let getIdToken = localStorage.getItem('idToken');
    if(getIdToken !== null){
      let newDateTime = new Date().getTime()/1000;
      const newTime = Math.trunc(newDateTime);
      const splitToken = getIdToken.split(".");
      const decodeToken = atob(splitToken[1]);
      const tokenObj = JSON.parse(decodeToken);
      const newTimeMin = ((newTime) + (5 * 60)); //adding 5min faster from current time
      //console.log(newTimeMin, tokenObj.exp)
      if(newTimeMin > tokenObj.exp){
          this.tokenRefresh();
          console.log('token updated');
      }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新令牌方法

tokenRefresh(){
    const poolData = {
      UserPoolId : // Your user pool id here,
      ClientId : // Your client id here
    };
    const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
    const cognitoUser = userPool.getCurrentUser();
    cognitoUser.getSession((err, session) =>{
      const refresh_token = session.getRefreshToken();
      cognitoUser.refreshSession(refresh_token, (refErr, refSession) => {
          if (refErr) {
              throw refErr;
          }
          else{
              //this provide new accessToken, IdToken, refreshToken
              // you can add you code here once you get new accessToken, IdToken, refreshToken
          }
      }); 
    })
}
Run Code Online (Sandbox Code Playgroud)


Aus*_*lfe 5

这将返回给您一个 AccessToken 和一个 idToken。

fetch("https://cognito-idp.<cognito-user-pool-region>.amazonaws.com/", {
    headers: {
        "X-Amz-Target": "AWSCognitoIdentityProviderService.InitiateAuth",
        "Content-Type": "application/x-amz-json-1.1",
    },
    mode: 'cors',
    cache: 'no-cache',
    method: 'POST',
    body: JSON.stringify({
        ClientId: "<cognito-user-pool-client-id>",
        AuthFlow: 'REFRESH_TOKEN_AUTH',
        AuthParameters: {
            REFRESH_TOKEN: "<cognito-refresh-toke>",
            //SECRET_HASH: "your_secret", // In case you have configured client secret
        }
    }),
}).then((res) => {
    return res.json(); // this will give jwt id and access tokens
});

Run Code Online (Sandbox Code Playgroud)