Expired RefreshToken is not handled properly
See original GitHub issueDo 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:
- Created 5 years ago
- Comments:5 (3 by maintainers)
Top GitHub Comments
@PerfectPixel thanks for the analyzing. I see what’s happening. The
user.getUserData
method should only be called when theuser.getSession
succeeds. Will do a fix for that.@powerful23 Some environment details:
Once the component mounts we call
Auth.currentAuthenticatedUser
and catch any errors:Lets trace the calls:
Auth.currentAuthenticatedUser()
Auth.currentUserPoolUser()
(here)Auth.currentUserPoolUser()
dispatches two concurrent async calls:user.getSession
(here) anduser.getUserData
(here). Both of them receive a callback that rejects or resolves the promise returned byAuth.currentUserPoolUser()
a.user.getSession
callsuser.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):
ConsoleLogger.js:84 [DEBUG] 43:33.476 AuthClass - get current authenticated userpool user
->Auth.currentUserPoolUser()
will be called nextConsoleLogger.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 ofAuth.currentUserPoolUser()
because the error message does not say that the user is disabled or deleted.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 ofAuth.currentUserPoolUser()
. But this will have no effect as the promise was already resolved.Result:
authState
issignedIn
with a user that should not be logged in anymore as the credentials are expired.