I'm creating a authentication route where user can login and u know the rest.
So after login im creating a refresh token (using JWT) which valid for 7 days, and with help of that refresh token i create access token (valid for 15 min) for logging in a users.
So to access a refresh token in frontend im storing this to cookie i.e refreshToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6I..." (whatever that string is). The problem is if any one access this refresh token and store it manually he can login as that user, until that jwt token expires. Im not storing Access token in cookie.
So What could be the solution for this, im thinking of storing refresh_token in user DB and update as user login.
Any suggestions will really appreciated :)
Related
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 am using jwt. I have some admin routes. I save the token in localStorage. In the payload of my token i have also admin property which is true or false. I wonder what if the 'admin' token from some user is stolen, and the old 'non-admin' token in the localStorage from the malicious user is replaced with the 'admin' token, then he will have access to the admin routes.
To prevent this on some way:
I will refresh the token on 10 minutes for example ( but the malicious user can do a lot of bad thinkgs in that 10 minutes - delete users from DB, delete configurations etc...).
Is there any other way to prevent and this 10 minutes 'possible attack'
Save the token in httpOnly and secure cookie. Is 100% sure that if i store my token in this kind of cookie, and nobody can edit it ? so when the 'admin' token is stolen the malicous user can't just copy paste the new token, like he could in localStorage ?
Don't save the token in LocalStorage since it is accessible to js, which means any XSS attack will have an access to the token.
Use 2 kind of tokens,
Short term access token (10 mins), it will be attached to each api request, it must contain something that is none "guess"ible some kind of hash, with it you will identify the user on the server side, it will be saved in memory.
Long term refresh token (12 hours or more), it will be saved in httpOnly + secure cookie. It has one purpose, with it your app can generated a new access token (when it expires). It must contain none "guess"ible hash to identify a user.
This will make your system much robust. If someone get somehow the accessToken, it will be expired in 10 mins, without it your api will refuse requests.
It is much harder to steal httpOnly + secure cookie, if someone managed to steal it, you can "revoke" the hash inside the token, so, it will become useless.
By revoking, it is simple as generate new hash in the db for the specific user/ entire db.
I always recommend to read this https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/
The entire idea on accessToken + refreshToken is explain there.
Some my code example, Axios Interceptor Response Token Refresh API called but getting Token is expired regardless in refreshToken API & lator all APIs
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.
I want to enforce a single user session feature for my Angular app because my customers share a single account with their coworkers.
The issue currently, with my implementation. is revoking a valid token stored a client's local storage, particularly a valid Refresh token.
The scenario is:
User 1 logs in with valid username and password, the bearer token will expire in an hour, the refresh token will expire in two weeks
User 2, uses the same username and password two hours later. User 2 is prompted that they are logged in on another device and asked the question of they would like to expire that session and start a new session.
User 2 says yes and the now User 1's session in invalid.
The problem is that User 1 still has a valid Refresh token.
I have no way revoke this refresh token. My Auth API will accept is valid and I will not know whether it is User 1 or User 2's refresh token.
Do I need to start storing refresh token values in my database to resolve this issue? I also thought I could use a different JwtAuthKeyBase64 for User1 and User2, as a way to invalidate User1's token but this doesn't seem like a good way to be using the ServiceStack JwtAuthProvider.
The JWT RefreshToken is used to contact the Auth Server to fetch a new JWT Bearer Token. It will only return a BearerToken if the User still has Access so you can lock the User Account by populating UserAuth.LockedDate which will prevent the user from retrieving a new JWT Bearer Token.
If you want more custom validation you can implement IUserSessionSource and throw an Exception in GetUserSession() to return an Error Response instead of the JWT Bearer Token.
After introducing JWT in my own application. I am facing some issues, might be I do it in wrong way. Please Suggest me the best way of implementation.
Technology Stack : (MERN) MongoDB Expressjs React Node.
After successfully login , I am creating a new JWT token by adding "user-id" in to it and return back to UI layer. At UI end I am storing that token in session storage. This token I am using for all further requests to the server. Before going to the controller I am checking Token in middleware for validtaion by using JWT verify. if successfully verified then next() else return an error with an invalid token.
Issue accurs now :
Register with USER 1
Login with USER 1
After successfully login copy Token from session storage.
Then Logout USER 1
Register with USER 2
Login with USER 2
Paste in session storage Token of USER 1 into USER 2
After refreshing a page USER 1 dashboard again instead of USER 2.
Any help or suggestions for following two points:
How should I manage user Session by JWT?
How should I manage API Authentication by JWT?
You should either not store tokens in the browser session or at least delete it when logging out. The token contains all information about the user as well as the signature, that verifies the validity of the token. If you copy & store it, it is still valid. Logging out the user doesn't invalidate the token.
You should add an expiry to the token to make it valid only a short time, but you need to refresh it then in intervals before it gets invalid. The normal way to do this is to use a refresh token which has a longer interval and keeps the user from logging in again and again.
When the user logs out, you should stop re-issuing access tokens from the refresh token.
See https://jwt.io/introduction/ for further information about JWT.