最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to restore an expired token [AWS Cognito]? - Stack Overflow

programmeradmin2浏览0评论

I'm using AWS for my website. After 1 hour the token expires and the user pretty much can't do anything.

For now i'm trying to refresh the credentials like this:

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

the thing is, after 1hour, the login token gets refreshed without a problem, but after 2hrs i can't refresh the login token anymore.

i also tried using AWS.config.credentials.get(), AWS.config.credentials.getCredentials() and AWS.config.credentials.refresh() which doesn't work either.

The error messages i'm getting are:

Missing credentials in config

Invalid login token. Token expired: 1446742058 >= 1446727732

I'm using AWS for my website. After 1 hour the token expires and the user pretty much can't do anything.

For now i'm trying to refresh the credentials like this:

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

the thing is, after 1hour, the login token gets refreshed without a problem, but after 2hrs i can't refresh the login token anymore.

i also tried using AWS.config.credentials.get(), AWS.config.credentials.getCredentials() and AWS.config.credentials.refresh() which doesn't work either.

The error messages i'm getting are:

Missing credentials in config

Invalid login token. Token expired: 1446742058 >= 1446727732

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Feb 20, 2018 at 14:32 DavidDavid 1,17412 silver badges38 bronze badges 5
  • are you getting your token by this authentication flow? if so, you must configure a TokenDuration when calling GetOpenIdTokenForDeveloperIdentity – guijob Commented Mar 5, 2018 at 22:58
  • the maximum duration for credentials is 1 hour. this is what i've set it to. – David Commented Mar 6, 2018 at 9:26
  • so you'll need to request another to your developer identity – guijob Commented Mar 7, 2018 at 4:30
  • It is common for access tokens to expire after 3600 sec, after that we need to make another api call using a "refresh token", to get the access token again(a new one). – Innocent Criminal Commented Mar 7, 2018 at 14:57
  • @InnocentCriminal I'm trying it like you've just mentioned since 2 days now, still can't get it to work. – David Commented Mar 7, 2018 at 15:30
Add a comment  | 

4 Answers 4

Reset to default 7

After almost 2 weeks i finally solved it.

You need the Refresh Token to receive a new Id Token. Once the Refreshed Token is acquired, update the AWS.config.credentials object with the new Id Token.

here is an example on how to set this up, runs smoothly!

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

Usually it's solved by intercepting http requests with additional logic.

function authenticationExpiryInterceptor() {
 // check if token expired, if yes refresh
}

function authenticationHeadersInterceptor() {
 // include headers, or no
}}

then with use of HttpService layer

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

It could be solved by proxy as well http://2ality.com/2015/10/intercepting-method-calls.html

In relation to AWS: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Credentials.html

You're interested in:

  • getPromise()
  • refreshPromise()

Here is how I implemented this:

First you need to authorize the user to the service and grant permissions:

Sample request:

Here is how I implemented this:

First you need to authorize the user to the service and grant permissions:

Sample request:

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}

This will return a Json something like:

HTTP/1.1 200 OK Content-Type: application/json

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

Now you need to get an access token depending on your scope:

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 would be:

HTTP/1.1 200 OK Content-Type: application/json

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

Now this access_token is only valid for 3600 secs, after which you need to exchange this to get a new access token. To do this,

To get new access token from 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=refresh_token&
client_id={client_id}
refresh_token=REFRESH_TOKEN

Response:

HTTP/1.1 200 OK Content-Type: application/json

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

You get the picture right.

If you need more details go here.

This is how you can refresh access token using 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
  }
};

More discussion here: https://github.com/aws-amplify/amplify-js/issues/2560.

发布评论

评论列表(0)

  1. 暂无评论