I'm using the JWT to protect node js urls https://github.com/auth0/express-jwt
To create a JWT token user session i simply do:
-> auth/signup
-> jwt.sign(user_profile,secret,expireInMinutes:{900000000 /*almost never expires*/});
OR in case of login call
-> auth/login
-> jwt.sign(user_profile,secret,expireInMinutes:{900000000 /*almost never expires*/});
Every time a protected url is called i check for req.user
that is set up automatically by the JWT middleware.
Now I'm wondering:
1 - where does JWT tokens are stored when calling sign() ?
2 - do i have to verify() the token every time a protected url is called? if yes why?
3 - When i set a new token for an already signed user does the old token (if exists) gets deleted ? What if the expiration is not been set up or is 5 years for example?
4 - Why can't I set new tokens on same browser/app page ?
I get invalid signature error if i register a new token but the token matches (i checked)
It's like I can't signin more than 1 user on same browser
You must have already figured out the answers to all your previous questions using the previous responses from the other users, but I will try to clear things up a bit for others too:
1 - where does JWT tokens are stored when calling sign() ?
When you call sign, the signed token is not stored anywhere, it is
returned by the sign function, then you have to send it to the client
so that in can be stored on the client side. (e.g. session storage,
local storage or cookie)
2 - do i have to verify() the token everytime a protected url is called? if yes why?
Yes you do. The idea is once the client has the token, they will send
the token to the server each time they make a request. The token is
processed by the server to determine whether a particular client has
been authenticated already.
3 - When i set a new token for an already signed user does the old token (if exists) gets deleted ? What if the expiration is not setted up or is 5 years for example?
Slightly related to the answer on point 1. Calling the sign function
will just generate another token. The expiration of the token is
stored within the signed token itself. So each time the server gets a token
from the client, it checks the expiration as part of the token
verification. Its important to note that the signed token is just the
"user_profile" object that you passed in as a parameter during the
signing, plus extra fields like the expiration date which are added to
that object.
So a client can have multiple tokens stored on the client side. They
will all be valid as long as they have not yet expired. However, the
idea is to only send a token to the client when they have been
authenticated again after the old one has expired.
4 - Why i can't set new tokens on same browser/app page ? I get invalid signature error if i register a new token but the token matches (i checked) It's like i can't signin more than 1 user on same browser
The idea is to have 1 user per browser. Since in this case the browser
is the client. I cannot think of use cases where you would need to
have multiple users per browser/client so you were obviously doing
something wrong. That's not to say its impossible to send multiple
tokens to the same browser/client.
2 - do i have to verify() the token everytime a protected url is
called? if yes why?
Yes. But "verify" is a little confusing term.
- When client calls /authenticate, server first validates user credentials against database to make this user authenticated. And this "expensive" operation performed only once for whole token life. Then, server prepares JSON object, holding useful user info, and encrypts it to get JWT token.
- This token sent only once to client, stored in a browser, and then sent back to server on every client request to /api.
- During processing client /api request, server must "verify" token for validity (JWT does it for you). But this does not mean to check user credentials against database again. Only just decrypting token to get JSON object back, HMAC-SHA256 verification – quite fast.
- Having JSON object with useful user info (claims), server can allow or not this specific user to access requested resource under /api route.
During token verification, no database check of user credentials is needed, because server have to trust received and verified (successfully decrypted) token. No server sessions storage is required to identify user.
You can think of JWT tokens like a simple session info, stored on client in an encrypted form. But if you need to cache more data in a user session info, I think, you still need some sort of sessions storage on a server, rendering JWT idea to almost useless compared to traditional Session ID in cookies.
Sorry. this should be a comment on previous answer, but i don't have enough rep to comment so he it goes
@sbaang : Another reason to verify every time is thta there could be interesting "claims2 in the token, like allowing a user to access certain endpoints, not all of them. So in each verification you're not only verifying if the user is allowed to access the protected API, but that specific endpoint, based not on having a valid token but having a token that specifically allow it.