Access Token and Refresh Token flow - security

I have read about JWT and access token and refresh token. I understand that you have to set access token expiration in a very short time (minutes) and use refresh tokens to obtain a new access token whenever is expired.
Three things are not clear to me:
Who checks access token for expiration? Is client checking that and requesting a new access code by sending expired access token along with refresh?
Who checks refresh token for expiration? (obviously refresh token needs expiration as well although it takes longer to expire).
From my point of view if a refresh token is expired, the user must be prompted to re-login. This is something that needs to be avoided in some scenarios (mobile apps). How can it be avoided?

Answer your question:
The API use access token will return error when access token expired.
The API use refresh token to get a new access token will return specific refresh token related error.
About refreshing of the refresh token, please see the below answer.
Generally you need do some error handing for each API calling.
About refreshing of the refresh token
I investigate more, and this is what I found:
first time login and authorized to get access token and refresh token(optional), if access token never expire refresh token is not necessary. => https://www.oauth.com/oauth2-servers/access-tokens/access-token-response/, recently(2019/11/16), I found this really depend on the implementation of the API providers, for example, PayPal, They provide access token with expired time but without refresh token, so when the access token expired, you have to get a new access token again.
when access token expired, use the refresh token to get a new access token and refresh token(optional) => https://www.oauth.com/oauth2-servers/access-tokens/refreshing-access-tokens/. this time you have a new refresh token, which means you have a new refresh token every time you refresh a access token. if the response don't have a new fresh token, you only have the old refresh token from the first step.
If user don't use the app for a long time, then user don't have chance to refresh the access token and refresh token, then user need to re login again after long time when refresh token expired.
like #jwilleke said, even user do not use the apps, the server side or the apps can do it for the user automatically, then it will always have the new access token and refresh token.

Related

What is the purpose of the refresh token if it can be stolen as well?

Main purpose is security: Shortened access token is important, because if someone stoles an expired token, then the attacker cannot use it, because it is expired.
We can obtain new access token with refresh token without the client needs to login again. Refresh tokens live longer.
I still don't get why refresh tokens was invented, because it can be stolen the same way as access token, right? If someone stoles refresh token, then the attacker gets access token as well.
Refresh tokens are being sent on the network way less than access tokens, so if your network is being sniffed, they will find the refresh token every 30mins (for example) in one request, so the window for you to be exposed is very small (you need to be sniffing in the right moment and for a long time)
Refresh tokens can be revoked, so if a user's token is stolen, the user can revoke its refresh token, but with a stateless access token with a long expiration time, it's not possible to close a session
If you want to store your access tokens, so they are revokable and get rid of refresh tokens, then you are not using a stateless JWT token, so you have to hit your database for each request you receive to check if the token is still valid or not.

Should revoke refress token when get new access token?

I have API get new access token from refresh token but i wonder that:
should revoke refresh token and generate new refresh token when getting new access.
Case 1:
api/refresh token =>
{new_access_token,new_refresh_token} (refresh_token revoked)
Case 2:
api/refresh token =>
{access_token} (refresh_token not revoke)
What is bestpractive, im using Nestjs
If you will revoke refresh token each time, user refreshes the token, you technically would be same as just going with 1 access token.
Best way to approach this, would be case 2. Though you would add some expiration to refresh token and then user would have to relogin again and regenerate refresh token.
The idea of refresh token is to somehow have control over your access token without sacrificing UX(User Experience). If you revoke refresh token each time, user will have to relogin. If you keep refresh token though, user would only have to relogin on refresh token revocation. On refresh token layer you could add database checks to check if user is banned. This way you save extra external calls on access token layer.
Hope this answers your question

I've been working with the Google API. Sometimes my refresh token refreshes and other times it fails and causes a 'RefreshError.' Why? How to fix?

Error:
google.auth.exceptions.RefreshError: ('invalid_grant: Token has been expired or revoked.', {'error': 'invalid_grant', 'error_description': 'Token has been expired or revoked.'})
However, another app I use, with a different account, never runs into any issues. I use the same Python OAuth Quickstart for both.
Token has been expired or revoked.
Basically means just that either the user has revoked your access or google has. Users can remove your access directly in their google account when ever they want to.
Google expired tokens
If you are using a gmail scope, and the user changes their password. Your refresh token will probably be revoked.
If your app is still in testing and the refresh token is more then seven days old the users consent will be removed and the refresh tokens will be revoked.
If the refresh token has not been used in more then six months the refresh token will be revoked.
If the user authroizes you app you get a refresh token, if the do it again you get another refresh token. both will work. You can have up to 50 outstanding refresh tokens for a user. If you request again then the first one will be expired. Ensure you are always storing the most recent refresh token.
no matter what the cause your application should be configured in a way as to request authorization from them again if the refresh token has expired.

How to regenerate Refresh Token and Access Token on Resource Request?

I am trying implementing JWT Tokens(Access tokens and Refresh tokens), but I come to an issue on requesting a protected resource with an expired access token, while the refresh token is still valid.
I know that I should not use refresh tokens to request resources, refresh tokens should be used against authorization validators to revalidate/regenerate access tokens.
In my app, the User can log in by POST request with a valid credential to get Access token(exp. in 1min) and Refresh token(exp. in 10min.). Say now User making a request 30 sec later of login and sends both tokens, then tokens get checked and resource comes back. If now user makes a request after 2min and sends tokens, his access token is Invalid, in this scenario how can I proceed with the request and revalidate tokens.
I can think of middleware to validate and provide tokens and send that with the response, but is this the right approach?
Then I need to handle and restore tokens on the client-side for every response. Don't I?
Also, I do not want to prompt users to re-login. I am using Node and Express for Server and React on Client.
Here are your steps:
Try to login
Receive 401 from server when token is invalid
Request a new access token by making a new refresh request.
Set the new access token and refresh token
Retry original request
This has to be done on the client side because it is the audience that gets validated for authorization.
Usually we don't set the access token to expire every minute because the described process would add too much latency to the process.
Edit from #MComment:
5 min for access tokens and 30 min up to a few hours is what is generally recommended for respectively access and refresh tokens. Usually Authorization Servers offer "rolling refresh" - refresh token's expiration is renewed whenever you use it. This way a user stays logged in as long as they are actively using the website
You can update expired date of access token in every request, no need to regenerate token.
I think session time you set is not normal and recommended.
If you dont want user must re-login, make a forever refresh token, create a function in reactjs for re-generate access token by refresh token if it expired.
Revoke refresh token only when u want to logout from this client.

how to do authorization (nodejs, express) with two tokens (access/refresh)

Good evening, I ran into a problem that I need to make authorization more secure and without re-logging. I read on the Internet that you need to use two tokens (access and refresh), but how to properly do authorization with them. You can advise a resource where competent authorization with two tokens is made.
My Tech Stack:
MongoDB
ExpressJS
ReactJS
NodeJS
If you request authentication with offline_access scope, you'll geta refresh token in addition to an access token. Save this refresh token to the database and whenever you need to make another call on behalf of the user you can
Make the call using your existing access token. If you don't get a 401, then you're good.
If you did get a 401, your token is probably expired and then you can call the token end point on the authorization server with the refresh token and grant_type=refresh_token to get a new access token and try your call again.
Might make the most sense to always request a new access token using your refresh token before you make another call.
To my knowledge you only deal with access tokens for authorization. The refresh token is only there to refresh an expired access token. The refresh token is exchanged for a new access token - without needing to present authentication credentials again. The call also (typically) takes a fraction of the time than re-authenticating.
as soon as the user log-in, give it two tokens refresh and access, store the refresh token in the database, give access token a expire time (5-10 min approx or less depending on your requirement).
for each request user will use the access token and for each request backend should check for the expired access token.
if the access token is expired, user will get a new access token by sending the stored refresh token to the backend(using a dedicated endpoint), backend will than check whether the refresh token is present in the database or not, if yes a new access token with new expire time will be sent in the response.
the cycle will continue until the user logs-out, in that case the refresh token will be deleted from the database and after some time access token will also get expire.

Resources