Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Cognito - Invalid Refresh Token

Tags:

I am using the Amazon Cognito service with the amazon-cognito-identity-js library, and am having an issue refreshing a user's tokens, namely the id token.

When trying to refresh the users tokens by making an unauthenticated initiateAuth request, I receive a 400 http status in response, along with an "Invalid Refresh Token" error message.

POST https://cognito-idp.us-east-1.amazonaws.com/ 400 (Bad Request)

Uncaught Error: Invalid Refresh Token.

Why does it believe that I am passing in invalid refresh token?

// the refresh token
var reToken;

// pool config
var poolData = {
    UserPoolId : 'us-east-1_XXXXXXXXX',
    ClientId : 'XXXXXXXXXXXXXXXXXXXXXXXXXX'
};

// connect to user pool and 
// find the current user
var CognitoUserPool = AmazonCognitoIdentity.CognitoUserPool;
var userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(poolData);
var cognitoUser = userPool.getCurrentUser();

// if we found a user
if (cognitoUser != null)
{
    // get active user session
    cognitoUser.getSession(function(err, session)
    {
        // catch errors
        if (err) {
            alert(err);
            return;
        }

        // get the refresh token
        reToken = session.refreshToken.token;
    });
}

// get current epoch time
var curDate = new Date();
var currentEpoch = Math.round(curDate.getTime() / 1000);

// get the epoch when the token
// was last issued
var issuedEpoch = store.get('issued');

// set the refresh parameters
var refreshParams = {
    ClientId: 'XXXXXXXXXXXXXXXXXXXXXXXXXX',
    AuthFlow: 'REFRESH_TOKEN_AUTH',
    AuthParameters: { 'REFRESH_TOKEN': reToken }
};

// note: 30 minutes = 1800 seconds
// if a token was last issued over 30 minutes ago
if ( (currentEpoch - issuedEpoch) >= 1800 )
{
    // refresh the users token with a new token
    userPool.client.makeUnauthenticatedRequest('initiateAuth', refreshParams, (err, newToken) => {
        // catch errors
        if (err) {
            alert(err);
            return;
        }

        // do stuff with the returned token
        console.log(newToken)
    })

}

As an aside, i've tried using refreshSession() but it tells me that getToken() is not a function of refreshSession().

cognitoUser.refreshSession(reToken, (err, authResult) => {
    if (err) throw err;
    console.log(authResult)
});
like image 629
Crayons Avatar asked Oct 22 '17 22:10

Crayons


People also ask

How do I refresh my Cognito access token?

Initiate new refresh tokens (API)Pass REFRESH_TOKEN_AUTH for the AuthFlow parameter. The authorization parameter, AuthParameters , is a key-value map where the key is "REFRESH_TOKEN" and the value is the actual refresh token. Amazon Cognito returns new ID and access tokens after your API request passes all challenges.

What is refresh token expiration Cognito?

By default, Amazon Cognito refresh tokens expire 30 days after a user signs in to a user pool. When you create an app, you can set the app's refresh token expiration to any value between 60 minutes and 10 years.

How do you authenticate with tokens with Cognito?

Authenticating with tokensWhen a user signs into your app, Amazon Cognito verifies the login information. If the login is successful, Amazon Cognito creates a session and returns an ID, access, and refresh token for the authenticated user.

How do I know if my Cognito token is expired?

You can decode the JWT token and also cache this expiry along with the token. Every time the cache for the tokens is accessed, also check the current time against the cached expiry time. If expired, use the Refresh token to obtain the latest Access and ID token and cache the tokens and expiry again.


1 Answers

I've found the answer.

As it turns out, it wasn't really an invalid refresh token; at least in the sense of the object itself.

If you have device tracking enabled, then you must pass the users device key in the AuthParameters (which I wasn't doing).

I read through the description of device tracking, as found here, and it didn't seem applicable for my use-case so I simply turned it off (User Pool > Devices).

The above code worked after that.

like image 51
Crayons Avatar answered Sep 19 '22 14:09

Crayons