Amplify-js: AWS Amplify gives invalid jwtToken after an hour

Created on 20 Nov 2018  路  14Comments  路  Source: aws-amplify/amplify-js

* Which Category is your question related to? *
AWS amplify auto handling refresh token
* What AWS Services are you utilizing? *
aws-amplify
* Provide additional details e.g. code snippets *
axios.interceptors.request.use(function(config) { return Auth.currentSession() .then(session => { // User is logged in. Set auth header on all requests let accessToken = session.idToken.jwtToken; axios.defaults.headers.common["Authorization"] = accessToken; return Promise.resolve(config); }) .catch(() => { // No logged-in user: don't set auth header return Promise.resolve(config); }); });
This is the interceptor request I'm using for now to get latest valid token irrespective of the total time, since user is logged-in as https://github.com/aws-amplify/amplify-js/issues/446 and aws-amplify documentation tells that it is automatically refreshing token internally and Auth.currentSession() gives you the latest valid jwtToken everytime. But what I experience is:
I login: Auth.currentSession() keeps giving me the jwtToken that was received when logged_in. After an hour, the token was expired and Auth.currentSession() was still giving this previous expired token which caused my server to send me 401. How do I handle it? How do I keep getting latest valid refreshed jwtToken? Am I using it wrong or is it a bug or what? Please help ASAP!
Posting this issue as suggested by @undefobj .

Auth investigating

Most helpful comment

I just figured out that Auth.currentSession() is giving latest valid token where the line
axios.defaults.headers.common["Authorization"] = accessToken;
was not setting latest token in request headers. I've resolved it by replacing this line with

          config.headers.common.Authorization = accessToken;

@matamicen Thanks a lot for your coordination and help!

All 14 comments

@undefobj Waiting for the solution.

@thomasmichaelwallace can you please help me out here?

@mghazanfar are you signing in via Cognito User Pool? If so, can you verify there is an item with the key CognitoIdentityServiceProvider.......refreshToken in your local storage? Also can you verify there is a request InitiateAuth sent to the Cognito Service when you call Auth.currentSession after 1 hour from login?

@powerful23 I鈥檓 signing in with Auth.signIn() and I think yes. There is this refreshToken key too. Auth.currentSession() is called before every API hit. I鈥檝e been seeing this Auth.currentSession() call but I did not see this initiateAuth in the entire session with any API call. I confirm you about it after an hour from now.

refreshtokenexists
@powerful23
I assure that after signing in with Auth.signIn(), I have CognitoIdentityServiceProvider.......refreshToken in my localStorage. I have left my app signed in. I post here after an hour if it sends a request InitiateAuth or does not.

requestbefore1hour
This is the request sent to CognitoService when I'm calling Auth.currentSession before 1 hour from login. I'm waiting for 1 hour to pass so I can show you what is it showing in networks.

@powerful23 I see no calls for initiateAuth

@powerful23 @undefobj My APIs started giving me 401 as currentSession() was providing me with old token that was not refreshed. I sent an API request after 9 mins of this to test. After 9 mins, two calls were gone for Cognito Service after which I received a refreshed token and my server started to respond with the required response. So the observation is Cognito sends your initiateAuth call but a few minutes later to the time the token was expired. Please help

@mghazanfar we are using session = await Auth.currentSession() without any problem. It refresh the token in the right way. Did you try the await way?

@matamicen No. I have not used it this way. I'll try this and will get back to you! Thanks

@matamicen As I'm provided by invalid token after an hour, I used axiosRetry to retry my call when old token is sent and 401 is fetched. Before making the request, I set axios header by getting, assuming to have latest token, idToken using session = await Auth.currentSession() but it still gives me invalid idToken.

@mghazanfar I don't know Axios, so let's do this in order to avoid bugs in your code, build a special async function just with the await Auth.currentSession() like this one:

refreshToken = async () => {
     var session = await Auth.currentSession();
     console.log("Refreshed token: " + session.idToken.jwtToken);
}

then call this function manually with a button (after the your token expires after one hour) and copy the generated token from the console and use an external program to call your API such as POSTMAN, so use the generated Token and see what is going on. (make sure to put the token in the Authorization parameter in the HEADER of POSTMAN).

What do you think about that?

Hope this helps.

I just figured out that Auth.currentSession() is giving latest valid token where the line
axios.defaults.headers.common["Authorization"] = accessToken;
was not setting latest token in request headers. I've resolved it by replacing this line with

          config.headers.common.Authorization = accessToken;

@matamicen Thanks a lot for your coordination and help!

I am getting

401,{"message":"The incoming token has expired"}

How can i regenerate or refresh the token in this case?

export async function get (endpoint: string, data?) {
    const currentSession = await Auth.currentSession();
    const providerId = currentSession.getIdToken().payload.sub;
    const identityJwt = currentSession.getIdToken().getJwtToken();
    return GET(endpoint, data, identityJwt, providerId);
}
Was this page helpful?
0 / 5 - 0 ratings