We are using Cognito User Pools with a SAML federation to our company's IDP to authenticate users in our system, using a Flutter front end.
We have the authentication code flow set up, can successfully obtain a code and obtain tokens with this code from the oauth2 endpoint. However, I am struggling to get refreshed tokens using the refresh code.
Specifically, I am making a request to the ../oauth2/token endpoint, passing through the following parameters:
grant_type: refresh_token
client_id: {client id - same id used to request initial code and token set}
refresh_token: {refresh token obtained from above request}
This seems to follow the AWS documentation (I'm following https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html) and suggestions on other questions. However, on making this call, I am receiving 400 Bad Request with an error
of invalid_grant
. This occurs in both the Flutter code and a Postman request. Both make the request by including the above in a x-www-form-urlencoded body.
The AWS app client has no secret key enabled, and the User Pool is not set to remember devices, so it doesn't seem to be covered in other questions I looked through (e.g. Cognito User Pool: How to refresh Access Token using Refresh Token). The app client is also set to enable refresh token based authentication.
Looking at the AWS documentation, invalid_grant occurs when the refresh token is expired. However, the expiry period for refresh tokens for that app client are set at 30 days...and the above request is made a few minutes after the tokens are issued.
I understand that there is a Flutter SDK for Amplify, but we're most of the way there using API calls and WebViews. I'd prefer not to have to say we need to rebuild the auth flow again if I can help it.
Would anyone have any thoughts?
Thanks
CodePudding user response:
The following curl works for me:
curl --location --request POST 'https://{{domain}}.auth.us-east-1.amazoncognito.com/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'scope={{custom_scope}}' \
--data-urlencode 'client_id={{client_id}}' \
--data-urlencode 'refresh_token={{refresh_token}}'
I believe that the scope isn't necessary.
My advice is to revisit the SDK idea. The SDK will cover you in issues like creating an access token automatically, if it has expired. If you don't use it, you need to monitor the expiration time yourself. It isn't just an issue of simple API calls.