how handle refresh token service in AWS amplify-js

前端 未结 5 1473
终归单人心
终归单人心 2021-01-03 16:14

In my react project I am using AWS Cognito user pool for user management, for user authentication, I am using AWS Cognito idToken. after 90min the session will expire, then

相关标签:
5条回答
  • 2021-01-03 16:37

    After a long struggle, I found the solution to update the AWS Cognito refresh token, To do this I am using the 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');
          }
        }
    }
    

    Updating the token method

    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
              }
          }); 
        })
    }
    
    0 讨论(0)
  • 2021-01-03 16:37

    I have used the 'amazon-cognito-identity-js' and refreshed the toke every time it expired and it solved my problem , here is a code snippet for the tricky getJwtToken part :

        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());
      }
    
    0 讨论(0)
  • 2021-01-03 16:40

    This will hand you back an AccessToken and a 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
    });
    
    
    0 讨论(0)
  • 2021-01-03 16:48

    Calling Auth.currentSession() should solve your problem. Amplify-js abstracts the refresh logic away from you.

    Under the hood currentSession() gets the CognitoUser object, and invokes its class method called getSession(). It's this method, that does the following:

    1. Get idToken, accessToken, refreshToken, and clockDrift from your storage.
    2. Validate the tokens (i.e. idToken, and accessToken) to see if they have expired or not.
    3. If tokens are valid, return current session.
    4. If tokens are expired, invoke the refreshSession() method of the CognitoUser class, which communicates to the AWS Identity Provider to generate a new set of tokens.

    All you have to do now is either:

    1. Make sure to call Auth.currentSession() at regular intervals
    2. Always call Auth.currentSession() to get your token for each http request that you make.

    You could use a wrapper like this:

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

    Lastly, this github discussion also introduces a very good manual way to refresh your token and introduces a use case for when you should explore that option.

    0 讨论(0)
  • 2021-01-03 16:58

    Amplify will automatically keep the session fresh so long as it's active (i.e. the user is making api calls, etc.).

    If you want to force the session to stay active, even though they are not actively using your API, then the easiest thing to do would be to call Auth.currentAuthenticatedUser() at regular intervals.

    0 讨论(0)
提交回复
热议问题