3

I am using aws cognito in scala play framework based web app as user management solution. I am using following code to login.

var mIdentityProvider: AWSCognitoIdentityProvider = getAmazonCognitoIdentityClient;

def sessionLogin(userName: String, password: String): AdminInitiateAuthResult = {
val authParams: java.util.Map[String, String] = new java.util.HashMap[String, String]()
    authParams.put("USERNAME", userName)
    authParams.put("PASSWORD", password)
    val authRequest = new AdminInitiateAuthRequest()
      .withAuthFlow(AuthFlowType.ADMIN_NO_SRP_AUTH)
      .withUserPoolId("***")
      .withClientId("***")
      .withAuthParameters(authParams)
    val authResult = mIdentityProvider.adminInitiateAuth(authRequest)
    authResult
}

Above code returns accessToken, expiresIn, tokenType, refreshToken and idToken from aws cognito server. As per aws documentation, we can use refreshToken to get new accessToken or idToken when accessToken gets expired in order to continue user session. But in document it is not mentioned how to use refreshToken for this purpose. Any help regarding this would be appreciable. Thanks in advance.

Shashi Shekhar
  • 177
  • 1
  • 4
  • 16

2 Answers2

3

I figured it out myself. Following is working code

def refreshAccessToken(refreshToken: String): AuthenticationResultType = {
    val authParams: java.util.Map[String, String] = new java.util.HashMap[String, String]()
    authParams.put("REFRESH_TOKEN", refreshToken)
    val authRequest = new AdminInitiateAuthRequest()
      .withAuthFlow(AuthFlowType.REFRESH_TOKEN_AUTH)
      .withUserPoolId("***")
      .withClientId("***")
      .withAuthParameters(authParams)
    val authResult = mIdentityProvider.adminInitiateAuth(authRequest)
    val resultType: AuthenticationResultType = authResult.getAuthenticationResult
    resultType
  }
Shashi Shekhar
  • 177
  • 1
  • 4
  • 16
  • 1
    I have copied this code (it's almost the same as what I have anyway), and it fails with an invalid refresh token error :/ - I'm think I'm losing my mind. – PlexQ Jun 07 '20 at 22:19
  • In case, if you have called logout using aws API then it invalidate refresh token i.e. you cannot use refreshToken to get new accessToken but even after logout accessToken is valid for 1 hr. – Shashi Shekhar Jun 24 '20 at 11:33
0

Glad you found an answer to your question. To help make this more of a resource for others in the future, here are some helpful links:

The AWS docs on token refresh

The Mobile SDK for iOS and the Mobile SDK for Android automatically refresh your ID and access tokens if there is a valid (non-expired) refresh token present, and the ID and access tokens have a minimum remaining validity of 5 minutes. If the refresh token is expired, your app user must reauthenticate by signing in again to your user pool.

Note also that the Amplify API includes logic to help with this. See this Git issue, and specifically this comment which deals with keeping tokens fresh even during long-running operations:

I ran into a situation where my Cognito JWT token was expiring on long-running S3 uploads (fails at the 1 hour mark). I couldn't find anything that gave a solution as to how you refresh the token in the middle of a request, so after hours of digging through the Amplify lib and AWS SDK, I finally figured out a solution. You do have to use the AWS SDK directly (sorry Amplify Storage)

MyStackRunnethOver
  • 4,872
  • 2
  • 28
  • 42
  • Is there a way to just validate if refreshToken is valid or still not revoked without refreshing access token actually? Because if I use above code then it will create new accessToken every time I hit the the protected API. – Shashi Shekhar Feb 04 '20 at 09:15
  • Actually I wanted to use refreshToken to find out if user has signed out successfully because AdminGlobalSignOut revoke refreshToken but accessToken remains valid for 1 hour even after logout. Let me know if you have faced this kind of issues and found out solution for this. – Shashi Shekhar Feb 04 '20 at 09:21