Refresh the Session
Overview
When a user logs in using Auth Connect the application receives an AuthResult
that represents the authentication session. The AuthResult
object provides access to several types of tokens:
- ID Token: The ID token contains information pertaining to the identity of the authenticated user. The information within this token is typically consumed by the client application.
- Access Token: The access token signifies that the user has properly authenticated. This token is typically sent to the application's backend APIs as a bearer token. The token is verified by the API to grant access to the protected resources exposed by the API. Since this token is used in communications with the backend API, a common security practice is to give it a very limited lifetime.
- Refresh Token: Since access tokens typically have a short lifetime, longer lived refresh tokens are used to extend the length of a user's authentication session by allowing the access tokens to be refreshed.
The key take away is that OIDC authentication servers are typically set up to return a short lived access token along with an much longer lived refresh token. For example, the access token may expire after one hour with the refresh token expiring after five days. This allows the application to use the access token for a period of time and then refresh it after that time has elapsed. As such, the application needs to be able to detect that the access token has expired and request a refresh of the session.
We will build upon the application we created in the getting started tutorial in order to implement a token refresh workflow.
Let's Code
As mentioned previously, this tutorial builds upon the application created when doing the getting started tutorial. If you have the code from when you performed that tutorial, then you are good to go. If you need the code you can make a copy from our GitHub repository.
Create the Refresh Function
The refresh strategy used in this tutorial is:
- If a session exists, determine if the access token is expired.
- If the session token is expired it can be refreshed if a refresh token is available.
- If a refresh token is available, refresh the session and replace the existing stale session with the refreshed one. The user's authentication has been made valid again.
- If a refresh is required but either cannot be performed or fails, throw away the invalid stale session. The user is no longer authenticated.
Let's see how this looks in our authentication
utility function module.
Add a function that will refresh the auth result if it is expired.
Get the current authResult
. If it exists, determine if it needs to be refreshed.
If the current auth result is expired, create a new auth result by refreshing the existing one.
Only attempt the refresh if a refresh token is available. Note that the session will be set to null
if it is expired
and either there is no refresh token available or the refreshSession()
fails.
Add a function that will refresh the auth result if it is expired.
Get the current authResult
. If it exists, determine if it needs to be refreshed.
If the current auth result is expired, create a new auth result by refreshing the existing one.
Only attempt the refresh if a refresh token is available. Note that the session will be set to null
if it is expired
and either there is no refresh token available or the refreshSession()
fails.
Call the Refresh
With this logic in place, the next logical question is where to call it. As we will see when we protect-the-routes, it will make sense to perform the refresh as needed prior to appending the access token to outbound requests.
For the example here, however, we will modify our App component to check for a refresh when the application is mounted.
Next Steps
This code represents the basic flow needed for an Auth Connect session refresh. It can easily be expanded to support more advanced scenarios.
For example, let's say that rather than only refreshing expired sessions our application would like to also refresh sessions that are about to expire, let's say within the next five seconds. Rather than using AuthConnect.isAccessTokenExpired()
, your application could use a combination of receivedAt and expiresIn to calculate when to access token is due to expire and use the current time to detect if the access token has either expired or is about to expire shortly. The code can then preemptively perform the refresh in those cases.
We suggesting starting with the flow documented here and modifying it as needed to fit your requirements.
Happy coding!! 🤓