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

时间:2018-11-19 13:08:44

标签: amazon-web-services amazon-cognito aws-amplify

在我的react项目中,我正在使用AWS Cognito用户池进行用户管理,对于用户身份验证,我正在使用AWS Cognito idToken。 90分钟后,会话将终止,然后我需要使用新的idToken进行刷新。如何使用amplify-js处理AWS Cognito中的刷新令牌服务。我尝试过Auth.currentSession(),每隔1个小时就会打电话给我,但它对我不起作用。

5 个答案:

答案 0 :(得分:2)

经过长时间的努力,我找到了更新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');
      }
    }
}

更新令牌方法

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
          }
      }); 
    })
}

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

我已经使用了“ amazon-cognito-identity-js”并在每次过期时刷新了令牌,这解决了我的问题,这是棘手的getJwtToken部分的代码段:

    getJwtToken() {
    if (!this.activeUser) {
      return null;
    }

    const signInUserSession = this.activeUser.getSignInUserSession();
    const idToken = signInUserSession ? signInUserSession.getIdToken() : null;

    if (!idToken || idToken.getExpiration() * 1000 <= Date.now()) {
      if (!signInUserSession.isValid()) {
        const refreshToken = signInUserSession.getRefreshToken();
        return new Promise((resolve) => {
          this.activeUser.refreshSession(refreshToken, (err, session) => {
            if (err) {
              resolve(this.logout());
            }
            this.activeUser.setSignInUserSession(session);
            resolve(session.getIdToken().getJwtToken());
          })
        });
      }
      return Promise.resolve(idToken.getJwtToken());
    }

    return Promise.resolve(idToken.getJwtToken());
  }

答案 3 :(得分:0)

这将使您获得一个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
});

答案 4 :(得分:0)

致电Auth.currentSession()应该可以解决您的问题。 Amplify-js使刷新逻辑脱离您的视线。

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

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

您现在要做的就是:

  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();
};

最后,此github讨论还介绍了一种非常好的手动方式来刷新令牌,并介绍了何时应该使用该选项的用例。