【问题标题】:How to restore an expired token [AWS Cognito]?如何恢复过期的令牌 [AWS Cognito]?
【发布时间】:2018-07-30 22:52:17
【问题描述】:

我正在为我的网站使用 AWS。 1 小时后令牌过期,用户几乎无能为力。

现在我正在尝试像这样刷新凭据:

 function getTokens(session) {
   return {
     accessToken: session.getAccessToken().getJwtToken(),
     idToken: session.getIdToken().getJwtToken(),
     refreshToken: session.getRefreshToken().getToken()
   };
 };


function getCognitoIdentityCredentials(tokens) {
  const loginInfo = {};
  loginInfo[`cognito-idp.eu-central-1.amazonaws.com/eu-central-1_XXX`] = tokens.idToken;
  const params = {
    IdentityPoolId: AWSConfiguration.IdPoolId
    Logins: loginInfo
  };
  return new AWS.CognitoIdentityCredentials(params);
 };


 if(AWS.config.credentials.needsRefresh()) {
    clearInterval(messwerte_updaten);
    cognitoUser.refreshSession(cognitoUser.signInUserSession.refreshToken, (err, session) => {
      if (err) {
        console.log(err);
      }
      else {
        var tokens = getTokens(session);
               
        AWS.config.credentials = getCognitoIdentityCredentials(tokens);
       
        AWS.config.credentials.get(function (err) {
          if (err) {
            console.log(err);
          }
          else {
            callLambda();
          }
       });
     }
   });
 }

问题是,1 小时后,登录令牌刷新没有问题,但 2 小时后我无法再刷新登录令牌。

我也尝试过使用AWS.config.credentials.get()、AWS.config.credentials.getCredentials() 和AWS.config.credentials.refresh() 这也不起作用。

我收到的错误消息是:

配置中缺少凭据

登录令牌无效。令牌过期:1446742058 >= 1446727732

【问题讨论】:

  • 你是通过这个authentication flow获得你的令牌吗?如果是这样,你必须在调用GetOpenIdTokenForDeveloperIdentity时配置一个TokenDuration@
  • 凭据的最长持续时间为 1 小时。这是我设置的。
  • 因此您需要向您的开发者身份请求另一个
  • 访问令牌通常会在 3600 秒后过期,之后我们需要使用“刷新令牌”进行另一个 api 调用,以再次获取访问令牌(一个新的)。跨度>
  • @InnocentCriminal 我在尝试你刚才提到的 2 天后,仍然无法正常工作。

标签: javascript amazon-web-services amazon-cognito


【解决方案1】:

差不多 2 周后,我终于解决了。

您需要刷新令牌来接收新的 Id 令牌。获取 Refreshed Token 后,使用新的 Id Token 更新 AWS.config.credentials 对象。

这是一个如何设置的示例,运行顺利!

refresh_token = session.getRefreshToken();   // you'll get session from calling cognitoUser.getSession()

if (AWS.config.credentials.needsRefresh()) {

  cognitoUser.refreshSession(refresh_token, (err, session) => {
    if(err) {
      console.log(err);
    } 
    else {
      AWS.config.credentials.params.Logins['cognito-idp.<YOUR-REGION>.amazonaws.com/<YOUR_USER_POOL_ID>']  = session.getIdToken().getJwtToken();
      AWS.config.credentials.refresh((err)=> {
        if(err)  {
          console.log(err);
        }
        else{
          console.log("TOKEN SUCCESSFULLY UPDATED");
        }
      });
    }
  });
}

【讨论】:

    【解决方案2】:

    通常是通过附加逻辑拦截http请求来解决的。

    function authenticationExpiryInterceptor() {
     // check if token expired, if yes refresh
    }
    
    function authenticationHeadersInterceptor() {
     // include headers, or no
    }}
    

    然后使用 HttpService 层

      return HttpService.get(url, params, opts) {
         return authenticationExpiryInterceptor(...)
                .then((...) => authenticationHeadersInterceptor(...))
                .then((...) => makeRequest(...))
      }
    

    也可以通过代理解决http://2ality.com/2015/10/intercepting-method-calls.html

    关于 AWS: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Credentials.html

    您对以下内容感兴趣:

    • getPromise()
    • refreshPromise()

    【讨论】:

    • 我尝试了 aws 的所有方法,包括 getPromise() 和 refreshPromise() 没有任何效果
    【解决方案3】:

    我是这样实现的:

    首先您需要授权用户使用服务并授予权限:

    示例请求:

    我是这样实现的:

    首先您需要授权用户使用服务并授予权限:

    示例请求:

    POST https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/token&
    Content-Type='application/x-www-form-urlencoded'&
    Authorization=Basic aSdxd892iujendek328uedj
    grant_type=authorization_code&
    client_id={your client_id}
    code=AUTHORIZATION_CODE&
    redirect_uri={your rediect uri}
    

    这将返回一个 Json,如下所示:

    HTTP/1.1 200 正常 内容类型:application/json

    {"access_token":"eyJz9sdfsdfsdfsd", "refresh_token":"dn43ud8uj32nk2je","id_token":"dmcxd329ujdmkemkd349r", "token_type":"Bearer", "expires_in":3600}
    

    现在您需要根据您的范围获取访问令牌:

    POST https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/token
    Content-Type='application/x-www-form-urlencoded'&
    Authorization=Basic aSdxd892iujendek328uedj
    grant_type=client_credentials&
    scope={resourceServerIdentifier1}/{scope1} {resourceServerIdentifier2}/{scope2}
    

    Json 将是:

    HTTP/1.1 200 正常 内容类型:application/json

    {"access_token":"eyJz9sdfsdfsdfsd", "token_type":"Bearer", "expires_in":3600}
    

    现在这个 access_token 只在 3600 秒内有效,之后你需要交换它来获得一个新的访问令牌。为此,

    从刷新令牌中获取新的访问令牌:

    POST https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/token >
    Content-Type='application/x-www-form-urlencoded'
    Authorization=Basic aSdxd892iujendek328uedj
    grant_type=refresh_token&
    client_id={client_id}
    refresh_token=REFRESH_TOKEN
    

    回复:

    HTTP/1.1 200 正常 内容类型:application/json

    {"access_token":"eyJz9sdfsdfsdfsd", "refresh_token":"dn43ud8uj32nk2je", "id_token":"dmcxd329ujdmkemkd349r","token_type":"Bearer", "expires_in":3600}
    

    你猜对了。

    如果您需要更多详细信息go here。

    【讨论】:

    • 请再次检查我的问题,我已更新。授权用户并授予他们权限没有问题,我(和许多其他人顺便说一句)遇到的唯一问题是我无法刷新过期的登录令牌。
    • 查看我的答案@tipsfedora 的最后一部分。希望能帮助到你。您只需要在前一个 access_token 过期后(即在最后一个 access_token 被授予后 1 小时后)发出此 POST 请求。
    • 我的例程if(AWS.config.credentials.needsRefresh())的第一行在令牌过期(3600秒)后为真
    • 抱歉@tipsfedora 我以前从未使用过 AWS 库。根据我的经验,有时这些库似乎无法正常工作,而且很多时候它们表现得完美无缺。这就是为什么我更喜欢手动 API 调用。无论如何,好问题。
    • 没问题。至少,你试图帮助我,我真的很感激,谢谢!
    【解决方案4】:

    这是使用 AWS Amplify 库刷新访问令牌的方法:

    import Amplify, { Auth } from "aws-amplify";
    
    Amplify.configure({
      Auth: {
        userPoolId: <USER_POOL_ID>,
        userPoolWebClientId: <USER_POOL_WEB_CLIENT_ID>
      }
    });
    
    try {
        const currentUser = await Auth.currentAuthenticatedUser();
        const currentSession = currentUser.signInUserSession;
        currentUser.refreshSession(currentSession.refreshToken, (err, session) => {
          // do something with the new session
        });
      } catch (e) {
        // whatever
      }
    };
    

    更多讨论在这里:https://github.com/aws-amplify/amplify-js/issues/2560。

    【讨论】:

      猜你喜欢
      • 2020-04-07
      • 2021-12-21
      • 2016-05-19
      • 2018-01-20
      • 1970-01-01
      • 1970-01-01
      • 2020-02-05
      • 2019-05-28
      • 2015-09-19
      相关资源
      最近更新 更多