Best practice for generating refresh token with JWT - authentication

Background
I'm implementing an authentication system based on JWT and Refresh tokens but I had an hard time searching for serious documentation about the refresh token generation and handling.
The common scenarios I've found expect:
A short-live token JWT that is stateless and not stored on the server-side
A long-live refresh token that is stored somewhere on the client side and on the server-side and that allows to get new authorized JWTs.
Refresh token generation
My first question is about the refresh token generation. I've seen two main scenarios:
The refresh token is a simple random string or a uuid that it is stored (with its expiring time) on the server side and represent a long user session
The refresh token is itself a JWT containing the not-sensitive data of the user that has logged in and has itself an expiration
The first case is the simplest but allows to encapsulate session data only manually, the second case is more complex but allows to encapsulate the session data, the expiration and it is generated only by a secret held in the server (it means more security). In this last case, however, making the JWT persistent is against the JWT phylosophy and more effort is required for validating also this JWT and comparing the data.
Refresh token workflow
Prerequisites
Storing the refresh token on the client side is the only way to persist the session on something like a browser. However it has to been stored securely so there are two scenarios even here:
The refresh token get stored in the browser in something like the localStorage or the sessionStorage (less secure)
The refresh token is passed to the client using a HttpOnly cookie that are less reachable with Javascript.
Question
Assuming that we store the refresh token in an HttpOnly cookie I was wondering: does the endpoint /refresh_token, that returns a new JWT and a new refresh token, need to be authorized?
If the endpoint has to be authorized, I should have a valid JWT for validating my user without requesting username and password again. In a scenario where the user uses the web application in a browser, then he closes it, then after a while he returns to the web application (and the JWT has expired) this is not possible and requires the user to authenticate again.
If the endpoint is not authorized I cannot have, while validating the refresh token, a valid user instance to check the refresh token data against. So, the only thing that I can check is the validity of the refresh token with the store (or with JWT strategies). This solves the above-mentioned scenario but, is this safe enough?
Another scenario is that the endpoint accepts also expired JWTs, validates them and then it checks the refresh token.
How should the refresh token be validated for a secure implementation? What are the best practices about this?

Related

JWT Auth, Way to access AccessToken when you logged in

i'm having a diffculty with Access Token.
And i'm new in web dev, taking a role in front-end.
So far, my web site is connected with server for log in API, and i can verify user infomation after logged in at console.
However, i'm wondering the way to get access to Access Token which is issued from the server.
So, the logic is as follows,
When i sucess logged in with correct user information, AccessToken and Refresh Tokens are issued.
I needed a code to access to Access Token, so if i have, i can access to prevented pages (such as, MyPage)
The Access Token has 30min of expires, so after logged in 30min,the issued Access Token must be expired and lost its access rigth to private pages.
Summary !
I'm wondering the way to code the AccessToken in Client side to server side after logged in. Found some of informations that saying include Access Token in headers request in Client side.
How can i code whether the Access Token is expired after 30 min and reqesting again to issue the access-token when i access to private pages with access-token expired state.
Then, if server can find there is a refresh-token in Client side, then issues access token very easily.
Wondering should i put all of the pages that check wether AccessToken is alive?
Normally, it handle by token middle-ware between front-end to IdP(ID provider) server.
It automatically refresh the access token by refresh-token.
The middle-ware's roles
refresh token together with the access token when the user login is processed.
access token and refresh token are re-issued when the refresh is executed
saved the access token and refresh token into local storage (usually called cookies)
If an access token is expired when you execute an API, it will be able to execute the API with a new access token if a refresh token is valid
If an refresh token is expired when you execute an API, it will be able to execute the API with a new access token if a refresh token is expired after got new refresh token.
Popular IdP is Keycloak provides middle-ware for multiple languages.
Java, Javascript, Python, Spring Boot, Angular, React
sorry, I missed your question
I'm wondering the way to code the AccessToken in Client side to server side after logged in. Found some of informations that saying include Access Token in headers request in Client side.
The front-end access an access token and decode it for getting user's information, role and expires time
How can i code whether the Access Token is expired after 30 min and reqesting again to issue the access-token when i access to private pages with access-token expired state.
middle-ware takes care the life time of access token
Then, if server can find there is a refresh-token in Client side, then issues access token very easily.
Yes,
Wondering should i put all of the pages that check wether AccessToken is alive?
It stored in local storage in single place and use it from mutiple pages
There are a few things I might not agree with in #BenchVue answer:
Client should retrieve user data from ID-tokens only. Access-tokens audience are resource-server(s), can be opaque and should be used only as authorisation headers.
Authorization-server (middle-ware in the answer) defines tokens expiries. It does not refresh it auto-magically. Clients must handle tokens refreshing, which can be done pro-actively as OAuth2 token responses contain expiry in adition to the token itself (even for opaque token).
Do not code a gripped weel. Pick a lib. You're very very likely to make security breaches otherwize. Plus you'll waste a lot of time implementing stuff like:
redirection to authorization-server for login / logout when user tries to access a protected route
silent access-token refreshing (just before it expires) using refresh-token
JWT adding as Bearer Authorization header to secured resource-server
etc.

sharing a refresh token for an user in multiple browser

I am currently implementing login using jwt.
I stored access token and refresh token in cookies, verify the validity of refresh token, and reissue the access token.
Once logged in, a new access token and refresh token are issued and stored on the client side.
Here, the refresh token is stored in the server-side redis, and if it turns out to be a different token compared to the refresh token held by the client, the login is requested again.
I implemented it in this way considering the possibility that refresh token might be stolen, but there is one problem with this method. If the same user logs in from another browser or from another device, he or she must log in again with the browser he or she previously logged in with. Because whenever a new login occurs, the refresh token stored on the server is replaced by this.
What should I do in this case? It seems that there are cases where refresh tokens are stored on the client without saving them on the server, but in that case, did you not consider the possibility that refresh tokens might be stolen? We set HTTP only when saving to cookies. Is this enough to be safe? I'm looking forward to hearing from you.
The solution I came up with is to provide the refresh token of the server and save it to the client if you log in from another device and do not have the refresh token. In this way, you can use the same refresh token while using the existing refresh token comparison method, so you can ensure that you are the same user on multiple devices. Is that a good idea?

JWT auth flow using access token and refresh token

I'm working on a project (nothing production-level, only for leveling up my skills) and I'm using JWT to handle authentication.
From what I've read, using a JWT only as an access token is quite unsafe, and hence we need refresh tokens. So, on login, the server returns an access token and a refresh token (which I will be storing in an httpOnly cookie). The access token expires in a short time, but the refresh token is used to get a new one when it does.
My question is, when do we use the refresh token to get a new access token? Is it when the user wants to get a protected resource and finds that the access token is expired (and the refresh token has not) or do we send a new access token each time the user wants to get the protected resource? I'm confused about when and where the refresh token comes into play.
(I'm using React for the frontend and Nodejs for the server)
You're using some security token so it mean that your system has some protected resources. Those resources can only be accessible on successful validation of the token. As you're using the JWT Token (usually for stateless authentication) and your system is granting both access_token and refresh_token to the client, so on server side you can use some authentication interceptor to validate the access_token in the each private request and return some error code on token expiration. On the client side you could also use some filter which should capture the error code and by utilizing the available refresh_token it should request for new access_token from the server. In case of refresh_token expiration your system should follow the route of fresh authentication.
The refresh token can be used at any time to request a new access token. Checking the validity of the access token before he request is one way of accomplishing that. Another common practice is to refresh the access token if it is within a certain timeframe of the current token expiring. A simple cronjob can work in this case. If you assume the access token is not used in multiple places (which it shouldn't be) then the current access token can be invalidated when the new access token is created. Also, for maximum security, the refresh token should be replaced with the access token. This limits security risk around a long-living refresh token becoming compromised.

Should access tokens be refreshed automatically or manually?

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
User authenticates with username and password. The API sends back a short lived access token containing his data, and a long lived refresh token.
For every request that requires authentication/authorization, the user will send both tokens on the request headers.
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
User authenticates with username and password. The API sends back a short lived access token containing his data, and a long lived refresh token.
For every request that requires authentication/authorization, the user will send his access token.
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?
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 has a lot of detail on the messages in a full UI and API solution.
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.
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 !
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

Custom (Non-OAuth) Refresh Token Implementation

I'm working on an application that uses a token-based authentication system, where the user provides their username / password and receives a token in return (the token gets saved to the database as well). Then subsequent requests will include this token as a custom header and we can use this to identify the user. This all works fine.
Right now if the user doesn't login for 3 days, we expire the token. I was reading a little about refresh tokens in OAuth and I was wondering if I could somehow implement something similar. i.e. when providing the auth token, I also provide a refresh token which can be used later to request a new auth token. In terms of security though, it seems quite similar to just never expiring the user's auth token in the first place. Should I be sending additional information with the refresh token to validate the user?
In OAuth2, the resource server and authorization server are often not the same.
The refresh token is sent back to the client when the access token is issued and when the token is refreshed. The client needs to authenticate itself (using client id and client secret) to use the refresh token. The resource server never sees the refresh token.
Also, access tokens are not stored at the server side as they have a limited lifetime. Refresh tokens are stored and can therefore be revoked.