Im building an authentincation and authorization system in javacript using JWT token
basically when i login i store in httponly cookies:
JWT Token
JWT Refresh Token
user information (id, username, email)
JWT expiration (5 minutes from when it's generated)
When the JWT is still valid protected pages will do a remote check for user validity (i request an API passing the userId and the auth token as an authorization bearer)
the remote check can take some time (less than a second), but every protected page shows a loading spinner while checking; i was wondering how safe is assuming the user is logged in it the JWT is still valid (or the refresh token get a new JWT) and the cookie with the user data is present. No external requests involved, unless you need to refresh the JWT
i was wondering how safe is assuming the user is logged in it the JWT is still valid (or the refresh token get a new JWT) and the cookie with the user data is present
JWTs are not fit as a mechanism of managing sessions. A JWT has its own expiration time and this is regardless of the user's session. If you need to manage a user's session, just use mechanisms for sessions, and scrap the JWT.
Related
I'm currently working on a project with expressjs. For user authorization I use JWT tokens but until now only access tokens, because I just don't understand them together with a real example. So can somebody explain to me what the steps are the authorization goes through when someone logs into his account.
f.E.:
Refresh and Access Tokens get generated
Token gets stored into database etc.
Thank you in advance and have a great day
User sends a POST request with login credentials
Server authenticates and if successful, returns a JWT (usually in a httpOnly cookie). Server does not store JWTs in a database. The whole point of JWT is that authentication state is stored by the bearer of it.
For subsequent requests to protected endpoints, client needs to attach JWT. Server should check if JWT is expired and whether it has been altered.
Extensions that you might want to think about:
How to refresh JWTs:
There are different refreshing patterns that can be used. For
example, you can check the expiry of the JWT every time that your
server receives a request. If JWT is expiring soon, issue a fresh
JWT.
How to maintain authentication state on client-side without having to log in every time you refresh the page
How to really log a user out:
If you set the expiry as 30 minutes and a user logs out at the 15th minute mark, that JWT can technically still be used to access protected endpoints for another 15 minutes.
I am making a react application and using JWT for authentication.
As soon as a user logs in I issue a access token and set a http only cookie named jwt and value is refresh token. As per some articles I have read online it is suggested that access token have a short validity and refresh token have a long validity, so I set validity of access token to be 1 day and refresh token to be 25 days, (numbers are not very relevant). Now as soon as refresh token expires The user is automatically logged out.
Now the app I am developing is a data entry dashboard and I do not want the user to suddenly logout after entering a lot of data even if that happens once a month, so I want to know the industry standard to manage this kind of situation
There is a way to update refresh token without login-password pair:
When a refresh token expires a client have to get a new token pair (access, refresh tokens).
The client sends its access AND refresh tokens and receives a new pair (just like when authenticating with username:password).
You should track expiry of refresh tokens to prevent their reuse.
It is as safe as your flow because when a client gets logged out it understands that someone else already used its refresh token once. So it has to authenticate using username:password and invalidate the last refresh token.
I found an article explaining this flow
I am using Firebase authentication to authenticate users. Whenever, the user is logged in, I get the user's ID token with user.getIdToken(true) and set it on the local storage. With that token in the authorization header, I am requesting my back-end API.
On the back-end side, I am using Firebase admin SDK to authenticate the request and the user with the client-side ID token passed in the request authorization header.
This works for a while. But after some time I get error:
ExpiredIdTokenError: Token expired, 1620908095 < 1620915515
I saw that Firebase refreshes the ID token on its own. But I don't think that's the case. I have looked through the developer tools network tab, and there's also an observer method to check whenever the token has changed => onIdTokenChanged(), but the token is never refreshed.
I couldn't find any information on the Firebase docs either, and I was hoping if you could help me:
How can I generate a token without expiration limit to last until signed out or at least for some more time (1 week maybe)?
If I cannot the set the expiry limit of the token, what steps should I take so that I can send a valid unexpired token when I am request data from my back-end? Do I have to call user.getIdToken(true) every-time and get a fresh token before I request from my back-end API?
The idTokenChanged() observer is a bit misleading. It will fire when the token is refreshed, but the token is only refreshed automatically when you also use other Firebase products (like its database or file storage). In other cases, as you said you should call user.getIdToken(), which will refresh an expired token for you if necessary, everytime you call your API. You don't need to pass true into this method unless you want to have a completely fresh token everytime (which you most likely don't need).
To my knowledge you cannot control the expiration of tokens generated with the client SDK, for that you would need to generate your own tokens on the server.
Do I need to store the user data in the local storage after a user get authenticated. So that the next time the user won't need to login again. But it the case where I'm using a JWT authentication. Do I still need to store the user data and the token in the local storage? Because I've seen a lot of tutorial where both are stored, but I'm not able to see the utility of storing both in the local storage. Can't we verify the token when the user comes back and store the user data in the session storage?
When you are using JWT tokens you have to store them locally. For a REST API(probably you will use with JWT tokens) you have to send JWT tokens beside all of your requests. Because your USER API waits for a JWT token in a header or a post body. JWT tokens have information about a user to refer your user database E.g. userid, username. Do not store any user specific information in client side. A reference(userid) is enough to identify a user in your server.
If you use JWT tokens you HAVE TO store them manually-programmatically in your browser's local storage. But you can use cookies that are set by your server to make user logged in. In that case browser automatically stores your cookies and sends them with your further requests in a Cookie header.
I am working on an authentication system, implemented the front end using vuejs and back end with nodejs. User is able to register and login successfully. I am verifying user is logged in using jwt token. My problem is anyone can login by manipulating the localStorage jwt token value. Is there anyway to prevent it.
You should be using an asymmetric signature on your JWT token, and the private key should be available only to the server that creates the JWT. If this is the case, then it's highly unlikely that a user would be able to forge JWT claims.
Here's a step by step of how your server should prevent someone from changing their JWT info:
Your NodeJS server creates a new JWT using an encryption key (we'll call it secret-key) to create the signature, and it sends the token to the client.
The user decides they want admin access, so they change their permissions in their local JWT and send it to the server.
The NodeJS server re-signs the header and payload of the user's JWT using secret-key and compares that generated signature with the signature in the user's JWT. If they match, then nothing has changed about the user's JWT. If they don't match, then either the user changed something in the header or payload, or they tried re-signing the token with their own encryption key. Either way, your server can tell that the JWT isn't valid, and you can deny them access.