question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Expired RefreshToken is not handled properly

See original GitHub issue

Do you want to request a feature or report a bug? Bug

What is the current behavior? If you enter a page with expired credentials (expired refresh and access token). The error returned from AWS is swallowed and the user is handled as if they are logged in. Also, there is rather odd concurrency in Auth.currentUserPoolUser as CognitoUser.getSession and Cognito.getUserData are called in parallel. This results in user data being requested although it should already be known that this will fail as the credentials are expired.

What is the expected behavior? An exception should be re-thrown or the exception should be properly processed.

Which versions of Amplify, and which browser / OS are affected by this issue? Did this work in previous versions? 1.0.5 (did not work in previous versions, this is a follow up to #1289 and #1303)

You can turn on the debug mode to provide more info for us by setting window.LOG_LEVEL = 'DEBUG'; in your app.

ConsoleLogger.js:84 [DEBUG] 43:33.470 AuthClass - configure Auth
ConsoleLogger.js:100 {[DEBUG] 43:33.470 Parser - parse config: Array(3)}
ConsoleLogger.js:84 [DEBUG] 43:33.475 AuthClass - getting current authenticted user
ConsoleLogger.js:84 [DEBUG] 43:33.476 AuthClass - cannot load federated user from auth storage
ConsoleLogger.js:84 [DEBUG] 43:33.476 AuthClass - get current authenticated userpool user
ConsoleLogger.js:100 {[DEBUG] 43:33.482 AuthClass - getting user data failed: Error: User is not authenticated
    at CognitoUser.getUserData (http://localhost:3000/static/js/bun…}
ConsoleLogger.js:84 [DEBUG] 43:33.746 AuthClass - Getting current session
ConsoleLogger.js:100 {[DEBUG] 43:33.768 AuthClass - getting user data failed: Error: User is not authenticated
    at CognitoUser.getUserData (http://localhost:3000/static/js/bun…}
ConsoleLogger.js:100 {[DEBUG] 43:33.770 AuthClass - Getting the session from this user:: CognitoUser}
localhost/:1 POST https://cognito-idp.eu-central-1.amazonaws.com/ 400 ()
ConsoleLogger.js:100 {[DEBUG] 43:34.221 AuthClass - Failed to get the user session: {…}}
localhost/:1 POST https://cognito-idp.eu-central-1.amazonaws.com/ 400 ()
ConsoleLogger.js:100 {[DEBUG] 43:34.310 AuthClass - Failed to get the user session: {…}}
localhost/:1 POST https://cognito-idp.eu-central-1.amazonaws.com/ 400 ()
ConsoleLogger.js:100 {[DEBUG] 43:34.331 AuthClass - Failed to get the session from user: CognitoUser}
ConsoleLogger.js:100 {[DEBUG] 43:34.333 AuthClass - Failed to get the current session: {…}}
:3000/#/customers:1 Uncaught (in promise) {code: "NotAuthorizedException", name: "NotAuthorizedException", message: "Refresh Token has expired"}

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
powerful23commented, Aug 24, 2018

@PerfectPixel thanks for the analyzing. I see what’s happening. The user.getUserData method should only be called when the user.getSession succeeds. Will do a fix for that.

1reaction
PerfectPixelcommented, Aug 24, 2018

@powerful23 Some environment details:

  • We are using a user pools without identity pools (no federation)
  • We are using amplify with react but use our own react components as we set up users via admins and there are some showstoppers in amplify-react
  • We are switching over multiple pools on login

Once the component mounts we call Auth.currentAuthenticatedUser and catch any errors:

Auth.currentAuthenticatedUser()
  .then(user => {
    this._changeState({ authState: 'signedIn', authData: user });
   })
  .catch(err => {
    this.handleSignOut();
  })

Lets trace the calls:

  1. Auth.currentAuthenticatedUser()
  2. As we have no federation, the next call is to Auth.currentUserPoolUser() (here)
  3. Auth.currentUserPoolUser() dispatches two concurrent async calls: user.getSession (here) and user.getUserData (here). Both of them receive a callback that rejects or resolves the promise returned by Auth.currentUserPoolUser() a. user.getSession calls user.refreshSession (here) which will fail b. user.getUserData will also fail because both access and refresh token are expired.

So what happens with the two concurrent calls? Let’s have a look at the logging (but you can also step through):

  1. ConsoleLogger.js:84 [DEBUG] 43:33.476 AuthClass - get current authenticated userpool user -> Auth.currentUserPoolUser() will be called next
  2. ConsoleLogger.js:100 {[DEBUG] 43:33.482 AuthClass - getting user data failed: Error: User is not authenticated -> user.getUserData called its callback and resolved the promise of Auth.currentUserPoolUser() because the error message does not say that the user is disabled or deleted.
  3. ConsoleLogger.js:100 {[DEBUG] 43:34.221 AuthClass - Failed to get the user session: {…}} -> user.getSession called its callback and tries to reject the promise of Auth.currentUserPoolUser(). But this will have no effect as the promise was already resolved.

Result: authState is signedIn with a user that should not be logged in anymore as the credentials are expired.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Handling Expired Refresh Tokens in ASP.NET Core
I can refresh the access_token without any issues. The issue comes into play when the refresh_token is expired, revoked or invalid in some...
Read more >
Solved: OAuth Refresh token has expired after 90 days
OAuth Refresh token has expired after 90 days. We have encountered an issue on our live environment: The Multi Factor Authentication does not...
Read more >
OAuth 2.0 Refresh Token Best Practices - Fusebit
Refresh tokens expire after six months of not being used. Another example is LinkedIn API, where by default, access tokens are valid for...
Read more >
Understanding Refresh Tokens - Auth0
When access tokens expire or become invalid but the application still needs to ... Some of the reasons a refresh token may no...
Read more >
Refresh Tokens - OAuth 2.0 Simplified
If you do not get back a new refresh token, then it means your existing refresh token will continue to work when the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found