OAuth 2.0 Refresh Token Example

In this tutorial, you will learn how to refresh OAuth 2.0 access token using the Refresh Token OAuth 2.0 Grant Type.

For video lessons on how to secure your Spring Boot application with OAuth 2.0. and Spring Security 5, please checkout my complete video course OAuth 2.0. in Spring Boot applications.

To learn how to use other OAuth 2.0 grant types, please check out the following tutorials:

Refreshing Access Token

The refresh token can be used to refresh an access token, only if the refresh token has not expired yet. If the refresh token has expired, it can no longer be used.

Below is an example of an HTTP request to refresh an access token.

curl --location --request POST 'http://localhost:8080/auth/realms/appsdeveloperblog/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'client_id=photo-app-code-flow-client' \
--data-urlencode 'client_secret=3424193f-4728-4d19-8517-d450d7c6f2f5' \
--data-urlencode 'refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlYWQyMDZmOS05MzczLTQ1OTAtOGQ4OC03YWNkYmZjYTU5MmMifQ.eyJleHAiOjE1OTQ0MDc1NTgsImlhdCI6MTU5NDQwNTc1OCwianRpIjoiY2Y4ZTNlMjctZjE0ZS00OTEzLWFkNjgtYjk4MDlmZWIxY2Q0IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL2FwcHNkZXZlbG9wZXJibG9nIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL2FwcHNkZXZlbG9wZXJibG9nIiwic3ViIjoiMWRkZTNmYzMtYzZkYi00OWZiLTliM2QtNzk2NGM1YzA2ODdhIiwidHlwIjoiUmVmcmVzaCIsImF6cCI6InBob3RvLWFwcC1jb2RlLWZsb3ctcmVzdC1jbGllbnQiLCJzZXNzaW9uX3N0YXRlIjoiM2Y4ZWZmMTEtOGNlOC00OTZiLWE0NTQtZDliY2VkYjc1NDcyIiwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSJ9.dbfVSOhVmXiR8e1sRBid9P8yZyD0KgWNLTyd03gZKng'

Where:

  • grant_type – OAuth 2.0 Grant Type. This value must be “refresh_token” for it to work,
  • client_id – OAuth 2.0 Client Id. This value needs to be in the request for the Authorization server to be able to identify and authenticate a client application.  If the client application is confidential, then a client_secret also needs to be provided.
  • client_secret – An OPTIONAL OAuth 2.0 Client Secret. If the client application was created as a Confidential client and a client secret key was generated for it, then it must be included in the request. Otherwise, this value is optional,
  • refresh_token – a value of a valid refresh token previously issued to a client application.

If the above request is executed with valid request parameters and the request is successful, then the authorization server will generate a new access token. When using the Keycloak server, the response is similar to the one below.

{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICItNUlsX2I0cUktdWFvaEI3d244UHY3WEM2UEktU3BNbmZCRnlJZUx6QTJNIn0.eyJleHAiOjE1OTQ0MTM4NDgsImlhdCI6MTU5NDQxMzU0OCwiYXV0aF90aW1lIjoxNTk0NDEzNDQ2LCJqdGkiOiI5ZDlkOGQ3NC00MDJhLTQ2NTQtYTMyZC05NjNhNDRjZWI0YWQiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvYXBwc2RldmVsb3BlcmJsb2ciLCJzdWIiOiIxZGRlM2ZjMy1jNmRiLTQ5ZmItOWIzZC03OTY0YzVjMDY4N2EiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJwaG90by1hcHAtY29kZS1mbG93LXJlc3QtY2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6IjBkMjYzNjYzLTFiMGQtNDU5Mi1iNmIyLTVlZThlNTNhM2Y2MSIsImFjciI6IjEiLCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIn0.MUxk9FUHZ6Xp8PvHPglJwcOO0042KguYF220Sr1QHuSsNh0r6oRMCsojo91XlCKwoSFRK2hytnaAiSqXwu_nRJGrz8Eim_1lGD_W9rEe-xkyP9pOEjZ9phzzsMqG56s0VS88mjA5tIxIahPZ6Fli_aDs6ZRnnrd4_SomRVfs43f_AWdyOOYQR4CU4WMdvtJwqaZ8ZnJLBQSja-NZfroEaIbuc7azt4LX23FH0knxTaFzzrTafQYbH8kDmVm7HB9hIOZTCUTVwIS4-4J8R4deWrLF03um_ND_cgAWfME987fcQZY-oNT2yioLpRTMizhWtEz5Wacd-CMCAXywOfGZxA",
    "expires_in": 300,
    "refresh_expires_in": 1800,
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlYWQyMDZmOS05MzczLTQ1OTAtOGQ4OC03YWNkYmZjYTU5MmMifQ.eyJleHAiOjE1OTQ0MTUzNDgsImlhdCI6MTU5NDQxMzU0OCwianRpIjoiM2E1Y2M3OTAtNTBiZS00OWFjLWI2NjktNTNkZDhlMmNkODVkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL2FwcHNkZXZlbG9wZXJibG9nIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL2FwcHNkZXZlbG9wZXJibG9nIiwic3ViIjoiMWRkZTNmYzMtYzZkYi00OWZiLTliM2QtNzk2NGM1YzA2ODdhIiwidHlwIjoiUmVmcmVzaCIsImF6cCI6InBob3RvLWFwcC1jb2RlLWZsb3ctcmVzdC1jbGllbnQiLCJzZXNzaW9uX3N0YXRlIjoiMGQyNjM2NjMtMWIwZC00NTkyLWI2YjItNWVlOGU1M2EzZjYxIiwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSJ9.VB0_lafyjhf4zMRZ2GG5fL0sP1GpUZU0eUq0sOpBgPU",
    "token_type": "bearer",
    "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICItNUlsX2I0cUktdWFvaEI3d244UHY3WEM2UEktU3BNbmZCRnlJZUx6QTJNIn0.eyJleHAiOjE1OTQ0MTM4NDgsImlhdCI6MTU5NDQxMzU0OCwiYXV0aF90aW1lIjoxNTk0NDEzNDQ2LCJqdGkiOiJmOGI5ZjVkNy02MDA5LTQyMWMtODUyMS00ZmM3MjRkYjUwMDIiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvYXBwc2RldmVsb3BlcmJsb2ciLCJhdWQiOiJwaG90by1hcHAtY29kZS1mbG93LXJlc3QtY2xpZW50Iiwic3ViIjoiMWRkZTNmYzMtYzZkYi00OWZiLTliM2QtNzk2NGM1YzA2ODdhIiwidHlwIjoiSUQiLCJhenAiOiJwaG90by1hcHAtY29kZS1mbG93LXJlc3QtY2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6IjBkMjYzNjYzLTFiMGQtNDU5Mi1iNmIyLTVlZThlNTNhM2Y2MSIsImFjciI6IjEiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJLYXJnb3BvbG92IiwicHJlZmVycmVkX3VzZXJuYW1lIjoic2VyZ2V5IiwiZmFtaWx5X25hbWUiOiJLYXJnb3BvbG92IiwiZW1haWwiOiJzZXJnZXkua2FyZ29wb2xvdkBnbWFpbC5jb20ifQ.R1bUrXZ1kMBaDuCzHGlS0qZbcPn6Rgdx9tGrN8eD5m1glCJ3MbEI8aTpu6CyYiIk7zqLaYjSJ6Grktj0Ht_fyWzdXVmzCtApFcIhRNdhT1VUlFdAHbGr5JmDBvnD7xiV6rSNU78xOfhoRadEsucfypCHsp4QLB67lUtt5dBb2R2JUmoG4WMGfbAwq805XkuPwOg_4AvuUdLNSlId9FbtGOYwDK54YR78gdZIlqyZg7N-otyHF06tgmCQysjCDFWgMFdh5lTZ9JlqYkPO-O5KipxBbCoodTuCMF1-flO330sz6OC6DzPQgIEEjgs-dC4qqGAf3jBhI9792FhcNpNIXQ",
    "not-before-policy": 1593436696,
    "session_state": "0d263663-1b0d-4592-b6b2-5ee8e53a3f61",
    "scope": "openid email profile"
}

Note, that if the response does not contain a refresh token anymore, then the client application needs to assume that the same refresh token can be used to refresh the returned access token.

Below is an example of a similar HTTP request in Postman.

OAuth 2.0 Refresh Token Grant Type example in Postman

I hope this tutorial was of some help to you. Don’t forget to check other tutorials that demonstrate how to use the OAuth 2.0 authorization grant types.

Happy learning!

Leave a Reply

Your email address will not be published. Required fields are marked *