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)
});
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With