【问题标题】:how handle refresh token service in AWS amplify-js如何在 AWS amplify-js 中处理刷新令牌服务
【发布时间】:2019-04-21 20:31:33
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    致电Auth.currentSession() 应该可以解决您的问题。 Amplify-js 将刷新逻辑从您身上抽象出来。

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

    1. 从您的存储中获取idTokenaccessTokenrefreshTokenclockDrift
    2. 验证令牌(即 idToken 和 accessToken)以查看它们是否已过期。
    3. 如果令牌有效,则返回当前会话。
    4. 如果令牌已过期,请调用 CognitoUser 类的 refreshSession() 方法,该方法与 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();
    };
    

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

    【讨论】:

    • 我认为应该是 getIdToken() 因为 getAccessToken() 对我们不起作用。
    【解决方案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
              }
          }); 
        })
    }
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 感谢您的重播,对于自动更新,我需要在我的用户池设置中启用任何选项吗?我尝试使用amazon-cognito-identity-js 来做到这一点,但这对我也不起作用
      • 否 - 如果访问令牌超时(一小时后发生),Amplify 会自动尝试刷新。请注意,您在 Cognito 用户池控制台(常规设置 > 应用程序客户端 > 刷新令牌过期(天))中配置 刷新令牌到期 - 这是用户无需执行的最长时间重新登录。
      • Amplify 已经修复了这个问题,Auth.currentAuthenticatedUser() 不会自动刷新会话(可能是因为这是一个昂贵的调用)。您将需要执行类似于@techie18 解决方案的操作来手动强制刷新(即不要等待 1 小时)。基本上,您必须获取当前会话的刷新令牌,然后将其传递给 refreshSession
      • 您对此有多大把握,考虑到文档中的这一点:aws-amplify.github.io/docs/js/…“使用 AWS Amplify 进行身份验证时,您无需手动刷新 Amazon Cognito 令牌。令牌会自动刷新必要时到图书馆。”代码中的这个条件:github.com/aws-amplify/amplify-js/blob/master/packages/auth/src/…
      • 免责声明:不是放大专家,但必须使用 refreshSession。我们的应用程序中有一个自定义用例,我们需要强制刷新令牌,以便应用程序的状态知道后端的变化。我们依靠调用 currentAuthenticatedUser 直到几天前才刷新令牌,但是由于 accessToken jwt 保持不变,这种情况不再发生。只有当我们使用 refreshSession 时它才再次起作用。此外,不清楚“必要时”是什么意思。
      【解决方案4】:

      这会给你一个 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
      });
      
      

      【讨论】:

        【解决方案5】:

        我使用了 'amazon-cognito-identity-js' 并在令牌每次过期时刷新它,它解决了我的问题,这里是棘手的 getJwtToken 部分的代码 sn-p:

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

        【讨论】:

        • 你必须添加所有代码,你有这个变量“this.activeUser”不是代码的一部分,你没有解释如何解决这个问题。
        猜你喜欢
        • 2019-07-01
        • 2020-10-16
        • 2021-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-01
        • 2023-03-16
        • 1970-01-01
        • 2019-01-24
        相关资源
        最近更新 更多