14

In the last few days I've been reading on Authentication with refresh and access tokens, but this is one thing I can't find the answer to. Let's say an expired access token is sent. Should the backend automatically refresh it (if a refresh token was provided), or the refreshing should only be done at a refresh endpoint?

As an example, consider the two following auth flows:

Automatically Refreshing

  1. User authenticates with username and password. The API sends back a short lived access token containing his data, and a long lived refresh token.
  2. For every request that requires authentication/authorization, the user will send both tokens on the request headers.
  3. If the access token is expired, the API will check if a valid refresh token was sent, if it is active and if it belongs to the same user as the access token. If everything looks good then it will sign a new access token and update the response headers with it.

Front-end doesn't have to worry about refreshing the token, but it still has to look up response headers after each request to check if a new token was sent.

Manually Refreshing

  1. User authenticates with username and password. The API sends back a short lived access token containing his data, and a long lived refresh token.
  2. For every request that requires authentication/authorization, the user will send his access token.
  3. When the access token expires, the user will send his refresh token to the refresh/ route. The API checks if the token is valid. If everything looks good, it returns a new access token.

After every request, the client has to check if the token expired, and if it did it will have to perform a new request to refresh the token. More requests are being made to the server, but on the other hand responsibilities are better separated, since auth route is only responsible for handling access tokens, while the refresh token handling lives in another route.

I've had some hard time finding resources on the subject, so I'm not quite about sure which solution is better, or even if the solutions I described are correct at all. If I had to pick one, I would go with Automatically Refreshing, since less requests are made, and the client side usability looks better, but as I said, I'm not 100% on this, and thus I'm making that thread.

How should access tokens be refreshed?

2
  • what approach did you end up with ?
    – yasseros
    Jan 29, 2023 at 20:51
  • 1
    I went with manual refreshing.
    – Allan Juan
    Jan 30, 2023 at 12:02

4 Answers 4

11

It feels to me that you are missing a role here, which is that of the Authorization Server (AS):

  • UI redirects to AS to authenticate the user via password
  • AS issues an access token and refresh token, then returns them to the UI
  • UI calls the API for a while with the access token
  • Eventually the access token expires and the API returns a 401 response
  • The UI then calls the AS with the refresh the token to get a new access token
  • The UI then retries the API call with the new access token
  • Eventually the refresh token expires and the refresh attempt will fail
  • The UI then redirects the user to sign in again and the cycle repeats

It is always the client's responsibility to refresh tokens and only the access token should be sent to the API. The API's only OAuth job is verify the access token and authorize based on its contents.

It is possible that you have an API that is doing the job of the Authorization Server. I would aim to separate these roles. If it helps my Messages Blog Post shows some example messages from a full UI and API solution.

4
  • Under this scheme, where are the tokens stored by the UI? I think local storage is vulnerable, and HTTP only cookies seem to be the recommend place from my research. But if they are in HTTP only cookies, UI cannot access them via javascript. How does the UI access the AT to send to the API? If I were to guess, I'd say the AS sends AT in response body and RT in cookies. UI then can send AT to API. When AT expires, UI calls AS to refresh, but does not need to send any tokens because it is already in the cookies? Is this about right?
    – Joe
    Jul 26, 2023 at 1:55
  • Also, I have this authentication logic built into my API. Does this no longer work if the API and AS are the same, because then you would always be sending both tokens on every request?
    – Joe
    Jul 26, 2023 at 1:59
  • The AS does not issue cookies to apps, and the standard option here is to use a backend for frontend to deal with cookies. My blog's Final SPA uses this approach. Jul 26, 2023 at 6:23
  • @joe you need to have two cookies. HTTP only with token itself and another one with information about expiration. Jan 29 at 10:53
9

The implementations of the OAuth2-protocol I know use the flow you are describing under "Manual Refreshing". The client has to care himself about the refreshing.

The client can either check the access_token if it is still valid before every request or do a refresh after a failed request due to an invalid token response.

The access_token is short lived and so the risk sending it with every request and having it eavesdropped and misused is limited. The refresh_token is long lived. If you send the refresh_token with every request an attacker has a much greater chance to get hold of it.

If you send both token with every request you would not need the distinction between these two types. You would work with one long lived token only.

7

Following is the Main Disadvantage of using Automatic Refresh Token Rotation Scheme :-

Let's say the Client makes 2 API calls (API A and API B) at the same time. At the time of triggering these two API calls, the access token was expired. Both of these API calls are carrying the same expired access token and the refresh token (let's assume this refresh token is valid).

Let's assume API A gets handled by the server first. According to the Automatically Refreshing Scheme, the server will check the API A's access token, if that token is expired, server will check the refresh token and if that refresh token is verified (this refresh token is present in the database too), the server will create a new access token and a new refresh token (the refresh token that came with the API will be deleted from the database and will be updated with this new refresh token). These new tokens will be returned to the Client.

API B will follow the same flow. BUT its Refresh Token will be invalid because during the handling of API A, the refresh token was replaced in the database by a new token. API B's Refresh Token is not present in the Database and thus this request will fail.

If you have multiple APIs being called at the same time, Automatic Refresh Token Rotation Scheme will fail as the First API request will replace the Refresh Token when renewing the tokens and the remaining API requests will be coming with a Refresh Token which is not present in the Database !

I have implemented Refresh-token-Rotation System here.

0

My experience has been that the OAuth2 access_token requests dont like extra data meaning that you wont be able to send both the access_token and the refresh_token. That would lead to the Manual Refreshing scenario youve described as the only option

2
  • Why wouldn't I be able to send both tokens? Couldn't I just send them using x-refresh-token and x-access-token headers?
    – Allan Juan
    Nov 10, 2020 at 22:08
  • I suspect you will get an invalid request response Nov 10, 2020 at 22:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.