Game Changer Authentication Mechanism: Refresh Token!

Emin Fidan
Trendyol Tech
Published in
7 min readNov 13, 2023
Rocky at Duty

In the projects developed by the Trendyol team, security problems related to the “Authentication” mechanism were increasing as the technologies became obsolete. This is a natural process that exists within technology. When the technology begins to become obsolete and the vulnerabilities detected on it begin to increase, problems will also increase. Since the Trendyol team follows all technologies and innovations up to date, we discovered the refresh token and JWT structure in a short time after these technologies were introduced and completed the necessary research on them.

We worked to make this structure compatible with our systems as soon as possible. We worked together with the security team and developer teams to resolve the different problems encountered during the integration process and the security vulnerabilities specific to this structure. As a result of these studies, we switched to using Refresh Token as the Authentication mechanism in our applications where necessary. By following new technologies, we offer our applications to our users in the safest and highest level of user experience.

What is A Token?

Tokens are pieces of data that carry just enough information to facilitate the process of determining a user’s identity or authorizing a user to perform an action. All in all, tokens are artifacts that allow application systems to perform the authorization and authentication process.

What is a Refresh Token ?

Common identity frameworks and protocols use token-based strategies to secure access to applications and resources. For example, we can use OAuth 2.0 for authorization and OIDC for authentication.

OAuth 2.0 is one of the most popular authorization frameworks out there. It is designed to allow an application to access resources hosted by other servers on behalf of a user. OAuth 2.0 uses Access Tokens and Refresh Tokens.

When a user logs in, the authorization server issues an access token, which is an artifact that client applications can use to make secure calls to an API server. When a client application needs to access protected resources on a server on behalf of a user, the access token lets the client signal to the server that it has received authorization by the user to perform certain tasks or access certain resources.

What is the Purpose of a Refresh Token?

The main reason why refresh tokens exist is most that access tokens don’t live forever. An access token may expire after a specific period of time like a few hours. Hence, in order to avoid requesting that the client perform an activity like entering a username and password to retrieve a new access token, you can use refresh tokens to get a new access token.

Refresh tokens matter a lot because they can improve the user experience and the general security of an application. On the side of user experience, imagine forcing your users to log in every time they return to your application after the access token expires. Most popular services seamlessly allow users to return to their previous session by silently generating new access tokens using refresh tokens. And also make the application more secure.

Security Perspective

In a situation where a malicious user gets a hold of a valid access token, they can make requests on behalf of a user and access protected data. As a result, access tokens expire after some time and become invalid. Anyway, if the user access token leaks attacker could use a very limited of time after the application uses the refresh token their access token will be trash. This mechanism ensures users a more secure environment.

How it’s Work?

Access/Refresh Token Workflow

1. First, a POST login request is sent to the user by the Client with the necessary credentials information to log in to the application.

2. If the information sent to the server is correct, the user is authenticated to the application. In the response, Access Token and Refresh Token information is returned to the user.

3. When the user makes requests within the application, the application adds access token information to the requests sent and these requests are sent.

4. Resource Server checks this access token value and if a valid value is received, it returns the requested resources to the user.

5. If the user whose Access Token has expired makes a request to the Resource Server with this token value, he will not receive a successful response because the Server will no longer consider this token value as valid.

6. When the Access Token is expired, the application will not return an error to the user. While the user continues his operations on the application, the Client App will request the Server with the Refresh Token information in the background and request a new Access Token value.

7. If the Refresh Token value sent by the Client is valid, the Server generates a new Access Token and sends it to the Client App.

  • These operations occur in the background without any interaction with the user, and the user continues to use the application without any interruption.
  • Steps 5, 6, and 7 in the flow above are repeated at regular intervals, without requiring any user interaction in the background.
  • To examine it more simply, the picture below is a good example of the flow.
Refresh/Access Token Workflow

Get Refresh Tokens

Below is an example POST request. In this way, when we request the application with credentials information if the information is valid, the application will return refresh and access token information to the user.

curl --request POST \ 
--url 'https://{yourDomain}/login' \
--header 'content-type: application/x-www-form-urlencoded' \
--data grant_type=authorization_code \
--data 'client_username={yourUsername}' \
--data 'client_password={yourPassword}' \
--data 'redirect_uri={https://yourApp/success}'

An example response returned to the user after a successful POST request.

{"token_type":"Bearer",
"expires_in":3600,
"access_token":"eyJraWQ…..rm8EA4osYg",
"scope":"offline_access openid",
"refresh_token":"i6mapTIAVSp2oJkgUnCACKKfZxt_H5MBLiqcybBBd04",
"id_token":"eyJraWQiOiJ…..XAn3ty6o-yeA"}

Exchange Refresh Token For Access Token

POST {tenant_url}/oauth2/token/{application_id}
{
'grant_type': 'refresh_token',
'client_id': ‘client ID’',
'client_secret': 'client secret',
‘refresh_token’: ‘NkTkDHFz.Dos5qUi...'
}

If the POST request is successful, a different access_token value is returned to the user than the previous one, as shown below.

{
'access_token': 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsMN0Y5NkVERjc5MEYx...',
'token_type': 'Bearer',
'expires_in': 18000,
'scope': ''
}

What is the Important Points for Implementation

  • A refresh token must not allow the client to gain any access beyond the scope of the original grant. The refresh token exists to enable authorization servers to use short lifetimes for access tokens without needing to involve the user when the token expires.
  • Auth0 limits the amount of active refresh tokens to 200 tokens per user per application. This limit only applies to active tokens. If the limit is reached and a new refresh token is created, the system revokes and deletes the oldest token for that user and application. Revoked tokens and expired tokens do not count against the limit.
  • They should have a short lifetime of less than 30 minutes.
  • The application must check the association between the access token and the refresh token, and check both the expired value and the integrity of these tokens themselves. Otherwise, scenarios such as obtaining another user’s access token with an expired token may cause some critical vulnerabilities.
  • When the application obtains a new access token with the refresh token, after checking the integrity of the refresh token value here, it must take the necessary information from this token and produce an access token suitable for the information here. If the application receives user information from another parameter in the request at this stage, for example ( email in the request body) The attacker can change the value here, generate an access token value for a different user, and abuse it.
  • Both token values used here are JWT tokens in structure. On the application side, the JWT token structure must be implemented carefully. The following these criteria are important:

- A strong encryption algorithm should be used.

- The key value with which we encrypt the token must be difficult to guess, have no semantic integrity, and must be long.

- The key value should be kept on the backend side and should not be in a place where the application can be accessed by users (response, .js files, GitHub…).

- The integrity of the tokens should always be checked.

- The token value should only be included in the responses that are required in the application; including it in different responses where it is not required increases the attack surface.

Conclusion

Refresh Tokens are a consummate way of providing sturdy security all while providing a great experience for users, provided it is being used in appropriate ways. That being said, it might not be completely essential for your applications and their needs.

About Us

We’re building a team of the brightest minds in our industry. Interested in joining us? Visit the pages below to learn more about our open positions.

Have a look at the roles we’re looking for!

--

--