PreciseSpeech
PreciseSpeech

Reputation: 347

How to use the refresh token of a session to get new jwt access token in amazon-cognito-identity-dart-2 package flutter?

I am currently using the Dart SDK amazon-cognito-identity-dart-2 for authentication and data upload in flutter.

When a refresh token is generated for a session, how can I use this refresh token to get new jwt access token before expiration?

Upvotes: 4

Views: 3409

Answers (2)

Tharindu Weerasinghe
Tharindu Weerasinghe

Reputation: 103

If your aim is to just get the jwt access token, it can be done after initiating the session without having to use the refresh token.

First you need to authenticate the user:

final userPool = CognitoUserPool(awsUserPoolId, awsClientId);
final cognitoUser = CognitoUser(email, userPool);
final authDetails = AuthenticationDetails(
      username: email, //user email
      password: password, //user password
);

CognitoUserSession cognitoUserSession = await cognitoUser.authenticateUser(authDetails);

Now you have an active cognito session. This session contains all the relevant tokens. You can get the jwt access token as follows:

String jwtToken = cognitoUserSession.getAccessToken().getJwtToken();

You may notice that this did not involve the use of refresh token, and you might wonder how to handle a scenario where the token might be expired. Luckily, this is straightforward. We can make sure whether the tokens are expired by checking

cognitoUserSession.isValid()

This returns false if the token is expired (by checking the elapsed time and token expiration time). Even if this returns false, we do not need to expressly work with the refresh token. We simply need to renew our session like this:

CognitoUserSession newSession = cognitoUser.getSession();

here, cognitoUser is the same user variable we authenticated at the start. When the getSession() method is called, if the current tokens are expired, our user object returns a new session with the new tokens (this is done inside the cognito user class using refresh token).

Therefore, what you need is to just check if the session is valid before getting the access token and if the session is expired simply call the getSession() method to renew it. Full implementation would look something like this:

class UserService {

  final _userPool = new CognitoUserPool(
    awsUserPoolId,
    awsClientId,
  );
  CognitoUser _user;
  CognitoUserSession _session;

  Future<bool> login(String email, String password) async {
    _user = CognitoUser(email, userPool);
    final authDetails = AuthenticationDetails(
        username: email, 
        password: password, 
    );
    try {
      _session = await cognitoUser.authenticateUser(authDetails);
    } on CognitoClientException catch (e) {
      return false;
    }
    return true; 
  }

  Future<String> getAccessToken() async {
    if (!_session.isValid()) {
      _session = await _user.getSession();
    }
    return _session.getAccessToken().getJwtToken();
  }
}

Disclaimer: I have returned a boolean from the login method for simplicity's sake. You would probably want to do something better at handling the exception

Upvotes: 4

Ashwani Sharma
Ashwani Sharma

Reputation: 41

you must use user auth details and the session and use it when user is logged in. refresh token function is available in

 CognitoUserSession session;
 awsToken(Store<AppState> store) async {
final userPool = CognitoUserPool(Aws.userPoolId, Aws.clientId);
cognitoUser = CognitoUser('+91801*******', userPool);
final authDetails =
    AuthenticationDetails(username: '+91801*******', password: '12345678');
authDetails.authParameters = [];

try {
  session = await cognitoUser.authenticateUser(authDetails);
  print("refreshed_token--" + session.getRefreshToken().getToken());
} on CognitoUserCustomChallengeException catch (e) {
  // handle CUSTOM_CHALLENGE challenge
  print(e);
} catch (e) {
  print(e);
}
}

Upvotes: 1

Related Questions