Javascript 如何还原过期的令牌[AWS Cognito]?

Javascript 如何还原过期的令牌[AWS Cognito]?,javascript,amazon-web-services,amazon-cognito,Javascript,Amazon Web Services,Amazon Cognito,我的网站正在使用AWS。1小时后,令牌过期,用户几乎不能做任何事情 目前,我正在尝试刷新凭据,如下所示: function getTokens(session) { return { accessToken: session.getAccessToken().getJwtToken(), idToken: session.getIdToken().getJwtToken(), refreshToken: session.getRefreshToken().g

我的网站正在使用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


通常可以通过使用附加逻辑拦截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(...))
  }
它也可以通过代理来解决

关于AWS:

您感兴趣的是:

  • getPromise()
  • 更新承诺()

    • 以下是我如何实现这一点的:

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

      样本请求:

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

      下面是我如何实现这一点的:

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

      样本请求:

      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}
      
      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}
      
      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
      
      这将返回类似以下内容的Json:

      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}
      
      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}
      
      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.1200ok 内容类型:application/json

      {"access_token":"eyJz9sdfsdfsdfsd", "refresh_token":"dn43ud8uj32nk2je","id_token":"dmcxd329ujdmkemkd349r", "token_type":"Bearer", "expires_in":3600}
      
      {"access_token":"eyJz9sdfsdfsdfsd", "token_type":"Bearer", "expires_in":3600}
      
      {"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=authorization_code&
      client_id={your client_id}
      code=AUTHORIZATION_CODE&
      redirect_uri={your rediect uri}
      
      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}
      
      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
      
      Json将是:

      HTTP/1.1200ok 内容类型:application/json

      {"access_token":"eyJz9sdfsdfsdfsd", "refresh_token":"dn43ud8uj32nk2je","id_token":"dmcxd329ujdmkemkd349r", "token_type":"Bearer", "expires_in":3600}
      
      {"access_token":"eyJz9sdfsdfsdfsd", "token_type":"Bearer", "expires_in":3600}
      
      {"access_token":"eyJz9sdfsdfsdfsd", "refresh_token":"dn43ud8uj32nk2je", "id_token":"dmcxd329ujdmkemkd349r","token_type":"Bearer", "expires_in":3600}
      
      现在,此访问令牌仅在3600秒内有效,之后您需要交换此令牌以获得新的访问令牌。为此,

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

      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}
      
      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}
      
      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.1200ok 内容类型:application/json

      {"access_token":"eyJz9sdfsdfsdfsd", "refresh_token":"dn43ud8uj32nk2je","id_token":"dmcxd329ujdmkemkd349r", "token_type":"Bearer", "expires_in":3600}
      
      {"access_token":"eyJz9sdfsdfsdfsd", "token_type":"Bearer", "expires_in":3600}
      
      {"access_token":"eyJz9sdfsdfsdfsd", "refresh_token":"dn43ud8uj32nk2je", "id_token":"dmcxd329ujdmkemkd349r","token_type":"Bearer", "expires_in":3600}
      
      你说得对


      如果你需要更多细节。

      差不多两周后,我终于解决了这个问题

      您需要刷新令牌来接收新的Id令牌。获取刷新的令牌后,使用新的Id令牌更新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");
              }
            });
          }
        });
      }
      
      refresh_token=session.getRefreshToken();//您将通过调用cognitoUser.getSession()获得会话
      if(AWS.config.credentials.needsRefresh()){
      cognitoUser.refreshSession(刷新令牌,(错误,会话)=>{
      如果(错误){
      控制台日志(err);
      } 
      否则{
      AWS.config.credentials.params.Logins['cognito-idp..amazonaws.com/']=session.getIdToken().getJwtToken();
      AWS.config.credentials.refresh((错误)=>{
      如果(错误){
      控制台日志(err);
      }
      否则{
      console.log(“令牌成功更新”);
      }
      });
      }
      });
      }
      
      这是使用AWS Amplify library刷新访问令牌的方法:

      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
        }
      };
      
      导入放大,{Auth}来自“aws放大”;
      放大({
      认证:{
      用户池ID:,
      userPoolWebClientId:
      }
      });
      试一试{
      const currentUser=wait Auth.currentAuthenticatedUser();
      const currentSession=currentUser.signInUserSession;
      currentUser.refreshSession(currentSession.refreshToken,(错误,会话)=>{
      //对新课程做些什么
      });
      }捕获(e){
      //随便
      }
      };
      

      更多讨论请点击此处:。

      您是通过此方式获得代币的吗?如果是这样,则在调用凭据的最大持续时间为1小时时,必须配置令牌持续时间。这是我设置的。所以你需要请求另一个开发者身份。访问令牌在3600秒后过期是很常见的,之后我们需要使用“刷新令牌”进行另一个api调用,以再次获取访问令牌(一个新的)。@InnocentCriminal我正在尝试,就像你刚才提到的那样,从2天后开始,仍然无法使其工作。我尝试了aws中的所有方法,包括
      getPromise()
      refreshPromise()
      无工作请再次检查我的问题,我已更新了它。授权用户并授予他们权限没有问题,我(以及其他许多人)遇到的唯一问题是无法刷新过期的登录令牌。请参阅我答案的最后一部分@tipsfedora。希望能有帮助。您只需在上一个访问令牌过期后,即在最后一个访问令牌被授予1小时后,才需要发出此POST请求。如果(AWS.config.credentials.needsRefresh())在令牌过期(3600秒)后为真,则例程的第一行
      对不起@tipsfedora我以前从未使用过AWS库。根据我的经验,有时候这些库似乎不起作用,很多时候它们的性能都完美无缺。这就是为什么我更喜欢进行手动API调用。好问题,没问题。至少,你试着帮我,我真的很感激,谢谢!