AWS provides us Amazon Cognito User Pools, which could be used as authorizer to control access to our application. Per Amazon Doc: Amazon Cognito user pools implement ID, access, and refresh tokens as defined by the OpenID Connect (OIDC) open standard:
name
, email
, and phone_number
.When we sign in the user pool using Amplify, we will obtain all those three tokens.
Normally, the ID token is for Authentication, and the access token is for Authorization. When calling the API method, we typically set the token to the request's Authorization header. So, it sounds like we should use the access token, doesn't it? Based on the doc, we could use either the ID token or the access token. However, as we tested, we should use the ID token. That's because:
Usually, we set the access token/the ID token expiration to be much shorter than the refresh token expiration. And then when the access token/the ID token expires, we can use an unexpired refresh token to get a new access token/ID token without asking users to re-login. The reason behind this is that the access token/the ID token is used to API method, in case they are stolen, the short expiry time could help minimize the damage.
Yes, with Amazon Cognito User Pool, we can set the app's refresh token expiration to any value between 60 minutes and 10 years.
Different to the access token/the ID token, which is the JWT token where we can get the expiration date, we cannot tell if the Refresh Token Expired or not from the token. But we can tell it from the auth_time of the refresh token/the ID token. For example, we set the refresh token expiration to 1 day, then we can use the following equation to get the refresh token expiration DateTime:
const authTime = user.signInUserSession.accessToken.payload["auth_time"];
const refreshTokenExpirationTime =
new Date(authTime * 1000 + 24 * 60 * 60 * 1000)
We set the access token expiration to be 60 mins, and the refresh token expiration to be 1 day. We use the Amplify library, which auto-refreshes the token when the access token expires, we basically get the 1-day session duration. Note that when the refresh token expires, the user has to re-login to get the new access token, ID token, and refresh token. So if the user is working on something when both the ID token and the refresh token are expired, then the unsaved work will be lost.
To understand how this works, let us use an example:
If your application has an auto-save feature, like Gmail App, then how the refresh token works as we discussed above should be fine. Otherwise, we may look into some solution to manually log out the user at the right time to avoid losing unsaved work.
Log out the user when the refresh token is about to expire in 60 mins, and we can check this when the page loads and when the user is active right after idle. In the other words, if the refresh token is not expired in 1 hour, then the user could get one more refresh, which could mitigate the session losing.
Implement the strict mode, for example, log out the user after the idle time is more than 15 mins, which could be a popup to allow the user to extend the session (by setting a longer refresh token expiration.) Also, log out the user when we detect the refresh token expiration time is in a day at the initial page load. But this solution will sacrifice the benefit of the refresh token.
We know both solutions are not great. So if you have any ideas, please leave your comments.