I'm building mobile and a web app. Both apps will be talking to a node server. I am using JWT for authentications.
Currently, I have the following code to generate an access token:
const token = jwt.sign({ user: body }, "top_secret");
I have some questions about access and refresh tokens:
How to create a refresh token?
What do refresh token look like?
Can I create a refresh token - similar to the way I'm creating an access token?
Is the refresh token only used to generate a new access token?
Can the refresh token be used as an access token?
How do you invalidate an access token
How do you invalidate a refresh token? Examples I've seen used databases to store refresh tokens. The refresh tokens are deleted when you want to invalidate an access token. If the refresh token would be stored in the database on the user model for access, correct? It seems like it should be encrypted in this case
When the user logs into my application, do I send both access token and refresh token? I read somewhere (can't remember where) that it's not good practice to send an access token and refresh token.
If its bad practice to send both access and refresh tokens, when do you send a refresh to the client? Should there be an endpoint where the clients request an access token?
What's a good expiry time for access tokens and refresh tokens?
Please note that in typical OAuth2 scenarios, the server issuing tokens (authorization server) and the API server consuming access tokens (resource server) are not the same. See also: Oauth2 roles.
To answer your questions:
How to create a refresh token?
You generate a string of sufficient entropy on the server and use it as a primary key to a database record in the authorization server. See refresh token syntax.
What do refresh token look like?
From https://www.rfc-editor.org/rfc/rfc6749#section-1.5,
A refresh token is a string representing the authorization granted to the client
by the resource owner.
The string is usually opaque to the client.
Can I create a refresh token - similar to the way I'm creating an access token?
You can, but refresh tokens are typically not structured tokens (like JWT) since they're consumed by the same server that issued them.
Is the refresh token only used to generate a new access token?
yes
Can the refresh token be used as an access token?
no
How do you invalidate an access token
Unless you're using introspection tokens, there's not a good way to invalidate them. Just keep their lifetime short.
How do you invalidate a refresh token? Examples I've seen used databases to store refresh tokens. The refresh tokens are deleted when you want to invalidate an access token. If the refresh token would be stored in the database on the user model for access, correct? It seems like it should be encrypted in this case
Delete if from the authorization server store. If the refresh token cannot be found on the server, it cannot be used to refresh an access token. A refresh token is typically just a primary key to a database record holding data about the client, user and expiration of the refresh token. While you don't want to leak your refresh token, it typically does require the client using them to present client credentials to use it.
When the user logs into my application, do I send both access token and refresh token? I read somewhere (can't remember where) that it's not good practice to send an access token and refresh token.
The user signs in at the authorization server. It returns an access token and refresh token (if your client is confidential) to the client. The client uses the access token alone to access your data on the resource server.
If its bad practice to send both access and refresh tokens, when do you send a refresh to the client? Should there be an endpoint where the clients request an access token?
Your client uses the refresh token in a call to the authorization server to get a new access token. So your client sends only the access token to the resource server and only the refresh token to the authorization server.
Whats a good expiry time for access tokens and refresh tokens?
That depends on your threat model. When your refresh token expires, the user is forced to authenticate again. Some products use refresh tokens that never expire, others use refresh tokens that are only valid for hours or days.
Related
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.
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.
I have an application that doesn't have user accounts so doesn't need a login. I'm currently authenticating using JWT via a /get-token endpoint in my api that's called as soon as the UI starts and returns a bearer token that's used for the calls for the calls moving forwards/
When that token expires, i'm a little confused at how to handle that. I was thinking using a refresh token but all the tutorials i've seen are passing the refresh token back to the UI, isn't that unsafe? I was always under the idea that the refresh token was internal and is only used on the server to refresh expired tokens.
What's the best way to handle this?
Refresh tokens carry the information necessary to get a new access token. In other words, whenever an access token is required to access a specific resource, a client may use a refresh token to get a new access token issued by the authentication server. Common use cases include getting new access tokens after old ones have expired, or getting access to a new resource for the first time. Refresh tokens can also expire but are rather long-lived. Refresh tokens are usually subject to strict storage requirements to ensure they are not leaked. They can also be blacklisted by the authorization server.
This is not a coding question, but a conceptual question for the correct handling and processing of a refresh token.
I have a single page app which issues a jwt token when logging in. The token works just fine. Now, I want to set the expiration to a low value, and use a refresh token to refresh the bearer token.
The question is, what claims should be stored in the refresh token? And what steps are supposed to be done to validate the refresh token before issuing a new token?
For example, right now my refresh token is a jwt which stores an expiration, so the client knows when the refresh token expires, and a username claim so that I know what user the refresh token is associated with.
So then when the refresh token is recieved:
Check that it is not expired.
Check that it has not been revoked.
Use the UserName in the refresh token to issue a new short-lived bearer token.
Is this the correct workflow for this? I just want to make sure I am not missing any security checks.
If your application is a single page application, you should not use long lived refresh tokens as you have no way of securely storing them.
OAuth2 defines a number of grant flows for different types of clients (which I've described here). Refresh tokens are only meant for confidential clients (like web applications living on a secured server).
Your refresh token is just as vulnerable to theft as your access token, since both are bearer tokens stored on the client.
Some OAuth libraries allow SPA or other non-confidential clients to get a new access token by talking to the token endpoint of the authorization server using a session token in a cookie. As long as the cookie is valid, the user can get a new access token. After that, the user will need to re-authenticate. Of course cookies can be marked secure and http only, making them harder to steal.
If you issue the JWT tokens from the same service endpoint that consumes the access tokens, you could have the client include a nonce in the token request that you hash and include as a claim in the token. The client can send the JWT in the Authorization header and the nonce in a custom header. Your token verification would hash the nonce again and compare it to the claim in the JWT. That way, if your token is stolen is harder to use without the nonce value. Of course, in a targeted attack, your nonce could also be stolen.
I have a question regarding security when working with refresh tokens. Lets say I have a web application which has access to a user's google calendar. Therefore I need to do the following steps:
Get a client ID and a client secret from Google.
The user of my web application gives permission to his calendar.
I get a refresh and an access token.
I send the access token to the Calendar API and get access to the user's calendar.
I can refresh the access token with the refresh token, which is saved in the database.
What would happen if someone gets access to my database or in general would have the refresh token of one of my users?
Can an attacker access the calendar with the refresh token or is the token linked to my client ID and client secret? Is it only possible to access the users calendar when my web application authenticates via the OAUTH2 API with my client ID and client secret?
Thank you
Yes, it is/should not be possible to use a refresh token with a different client than it was issued to.
Refresh tokens are typically opaque strings, but in the issuer they should be linked to the authenticated client. That is why you need to send your client is and secret along when you use the refresh token.
Assuming that the client is able to keep a client_id and client_secret from the attacker, the regular approach is to treat and store the refresh_token in the same way. So even though technically it is not possible to obtain a new access token without the client credentials, in practice the attacker would get a hold of the client credentials in the same way as he got hold of the refresh token.