aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.41k stars 2.11k forks source link

Invalid refresh token with AWS amplify #1268

Closed tarciosaraiva closed 6 years ago

tarciosaraiva commented 6 years ago

Do you want to request a feature or report a bug? Report a bug.

What is the current behavior? User logs in using USER_PASSWORD_AUTH authentication flow type, stays on the app for 1 hour. Moves on to another page on the app, a POST request to Cognito is issued to refresh the token and the response is HTTP 400.

The app invokes Auth.currentAuthenticatedUser() whenever moving between pages.

Request

POST / HTTP/1.1
Host: cognito-idp.ap-southeast-2.amazonaws.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://localhost:3000/properties/9310
content-type: application/x-amz-json-1.1
x-amz-target: AWSCognitoIdentityProviderService.InitiateAuth
x-amz-user-agent: aws-amplify/0.1.x js
origin: http://localhost:3000
Content-Length: 2051
DNT: 1
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

Request POST data

{
  "ClientId": "xxx",
  "AuthFlow": "REFRESH_TOKEN_AUTH",
  "AuthParameters": {
    "REFRESH_TOKEN": "...",
    "DEVICE_KEY": null
  }
}

Response

HTTP/2.0 400 Bad Request
date: Thu, 19 Jul 2018 01:34:47 GMT
content-type: application/x-amz-json-1.1
content-length: 70
x-amzn-requestid: ...
access-control-allow-origin: *
x-amzn-errortype: NotAuthorizedException:
access-control-expose-headers: x-amzn-RequestId,x-amzn-ErrorType,x-amzn-ErrorMessage,Date
x-amzn-errormessage: Invalid Refresh Token.
X-Firefox-Spdy: h2

What is the expected behavior? Expected the session to be successfully refreshed.

Which versions of Amplify, and which browser / OS are affected by this issue? Did this work in previous versions? The version of Amplify I'm using is @aws-amplify/auth 1.0.0. All browsers.

michaelcuneo commented 6 years ago

"Cache-Control: no-cache" makes me think that awsamplify has it's cache turned off... it's not storing the Refresh Token to use it later... that's just my first thought from a quick glance.

    // OPTIONAL - Configuration for cookie storage
    cookieStorage: {
    // REQUIRED - Cookie domain (only required if cookieStorage is provided)
        domain: '.yourdomain.com',
    // OPTIONAL - Cookie path
        path: '/',
    // OPTIONAL - Cookie expiration in days
        expires: 365,
    // OPTIONAL - Cookie secure flag
        secure: true
    },

This part of the aws-amplify config.

tarciosaraiva commented 6 years ago

@michaelcuneo not quite. LocalStorage has idToken + accessToken + refreshToken stored successfully. And the request POST data above contains the full refresh token.

We actually have a refresh token implementation using the aws-sdk happening in our back-end services and it works successfully.

michaelcuneo commented 6 years ago

I had a feeling my answer wasn't correct... I didn't look at it for long enough, but with the new information... I'm wondering why you have aws-sdk running alongside aws-amplify... what's the specific use case that's making you need to pull that in as well, I guess, you have a specific purpose for it that isn't covered in the aws-amplify API. Is there a sync between your local storage version of refresh token and the aws-amplify version of the refresh token so that when the access token expires it grabs a valid copy of the refresh token before requesting an access token?

tarciosaraiva commented 6 years ago

@michaelcuneo OK let me provide a bit more insight into my setup:

TL;DR the back-end reads the tokens from Cookies setup by the front-end once the user login and is able to refresh the id token and access token using the refresh token if either are not valid anymore.

The front-end SPA works independent and relies on the localStorage entries setup by aws-amplify. Once the tokens are invalid it's actually triggering the AWS call to refresh the token but it's not working.

I'm not sure if it's a problem with aws-amplify itself - could as well be a bug in Cognito - but the fact is that the refresh works when the back-end triggers it using aws-sdk.

Hugodby commented 6 years ago

I had a similar issue before. I use the currentSession() method instead and it refresh correctly the token.

/**
 * Return the Cognito User Pool token of the authenticated user.
 */
export function currentUserToken() {
  return Auth.currentSession().then((session) => {
    return session.idToken.jwtToken;
  });
}
tarciosaraiva commented 6 years ago

Thanks @Hugodby will give it a try :+1:

tarciosaraiva commented 6 years ago

So figured out what was happening. It seems to be a bug either in this library or with Cognito, haven't figured out yet.

Our users are being brought over using the User Migration Lambda, which means whenever they login they are migrated across. So far, so good. It also means that we need to use the USER_PASSWORD_AUTH authentication flow type instead of the default USER_SRP_AUTH.

And this is the problem: whenever we use the USER_PASSWORD_AUTH authentication flow type I get a HTTP 400 with a NotAuthorized exception.

I tested it by issuing a request with USER_SRP_AUTH in the authentication flow type and I got a successful token every time.

It seems that tokens issued by the USER_PASSWORD_AUTH are not being validated correctly in Cognito - it seems to be a problem in the platform, not in this library.

michaelcuneo commented 6 years ago

Is it a authentication level issue... can you adjust the authentication to aws_iam instead of Logged In Cognito User, then adjust your own code to reflect the authentication changes... ? i.e. Instead of allowing access to the resources based on individual signed in Cognito Users, allow the access to the entire aws_iam account, then assign Logged In User Pool access to the aws_iam accounts resources.

tarciosaraiva commented 6 years ago

@michaelcuneo I'm not sure I understand what you mean. Are you talking about this? https://docs.aws.amazon.com/cognito/latest/developerguide/resource-permissions.html

tarciosaraiva commented 6 years ago

I can confirm that this is not an issue with the library. Our user pool got misconfigured generating false negatives. Happy to close this!

tcchau commented 6 years ago

Hi @tarciosaraiva, if it won't divulge any secrets or security issues, would you mind explaining what the misconfiguration is/was? I am running into the exact problem, i.e. migrated user accounts and using USER_PASSWORD_AUTH to facilitate the migration trigger.

tarciosaraiva commented 6 years ago

Hi @tcchau our configuration is setup using terraform and I was fiddling with thr "Advanced Security" features in Cognito - among other things - that caused something in their engine to generate tokens with a certain signature that could not be verified using the USER_PASSWORD_AUTH method for some reason.

I've since recreated the user pool and all is well.

alondahari commented 3 years ago

https://github.com/aws-amplify/amplify-js/issues/498#issuecomment-413204103

github-actions[bot] commented 2 years ago

This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels or Discussions for those types of questions.