JWT token verification procedure to obtain the user object - node.js

In my current test node express project, I use JWT. For a POST route, I need the user who fires the request. Therefore I send the JWT with the request. In the NodeJs controller, I have access to the supplied token.
I decode this and then have the user email, exp and iat. Is it now correct that I only start a DB query with the decoded email of the user, with which I receive the user object?
Or do I have to do another validation step? I don't miss any other validation but I find it somehow unsafe.

I decode this and then have the user email, exp and iat. Is it now correct that I only start a DB query with the decoded email of the user, with which I receive the user object?
You can use the email from the decoded JWT token only after its validation. Once you validate it, you know that user information is legitimate unless your secret is compromised.
You need to use an auth middleware that will allow the request to access the next middleware and the controller logic.
Or do I have to do another validation step? I don't miss any other validation but I find it somehow unsafe.
If the encoded JWT token is validated correctly, you don't need to add any validation for decoded data, however, it is important to validate the data coming in the request (You can use Joi).

Related

how to refresh JWT Token after username update in NestJS?

I've been using Passport JWT for Auth and the payload for signing is username and seller.
Now the issue is that every time i update username and tries to fetch userdetails it gives 401. So i'm looking for a way to handle this gracefully using passport jwt in nestjs
How about using the user id and the seller id as payload? These values won't change and therefore the token stays valid even when the username changes

does JWT containing userID need verification from the database?

I sign a JWT (JSON Web Token) with userID and iat (issues at) like so
jwt.encode({sub: user.id, iat: timestamp}, jwtSecret);
When I receive a JWT from the client, I decode it to extract the userID. Do I need to validate the userID by checking its existence in the database every time I need to allow the user to access a secure route (see first example)? Or can I just assume that the user is who she says she is, and allow her to access the secure path?
My feeling is that I need to access the database to validate the user on every request, this would be expensive and defeat the purpose of using a JWT.
Your token is signed. If someone changes the token on client side, it would fail validation and the server side framework would reject it. Therefore you can trust your token.
Of course, the jwtSecret should be a secret only known by your authentication server and resource server.
You generate the token only if you trust the user who requested it.
You trust the token as long as it has not expired and can be verified with the secret.
The whole idea of JWT is that can verify the integrity of the claims contained within it. If you can decode successfully the token you can be sure that this token contains information previously encoded by you. For someone to pass malformed data has to also know the secret you use to sign the tokens.
For more information read this.

Token Based Authenication with Node/Express

I’m a little confused as to how JWT authentication works. Once a user is able to log in, my express server is responding with a token, which I store on the client side in local storage. With every request, I send that token. My question is, how do I limit a user to see his/her specific data (e.g., user profile)? Is the token alone able to determine which user is requesting the user data on the server side or would i have to send the username along with the token? Is this secure?
The JWT token will contains 3 parts, one of them called a payload and you will use it to store the user's id when he logs in. When the user sends a request with his token you will decode it and grab the id from the payload and then with a query to your database you can get the user's profile.
how do I limit a user to see his/her specific data (e.g., user
profile)?
If you get the id from the token's payload then you can compare it with the id of the profile that the user wants to see, if they are the same then it means that he wants to see his profile.
Is the token alone able to determine which user is requesting the user
data on the server side or would I have to send the username along
with the token?
No need for username, the token alone is sufficient because it identifies the user.
Is this secure?
Read this: http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/ there are other opinions of course, try implementing best practices and I think you'll be fine.

Why would I need to use passport package with jsonwebtoken for applying token based authentication on a NodeJs web API?

passport , passport-jwt , jsonwebtoken , express-jwt ..etc
I’m confused, when to use which and which to use with which?
I was building my own MEAN app not too long ago and ran into the same questions. This cleared it up very well.
https://jonathanmh.com/express-passport-json-web-token-jwt-authentication-beginners/
Basically, you use jsonwebtoken to generate the token. This is returned to the client who in turn sends it every time he makes a request. This is typically passed in the auth header. Passwort-jwt check this auth header and verifies it's validity. If it is invalid, it returns a 401, otherwise it populate your req.user.
passport-jwt:
In this strategy, server validates user credentials and returns encrypted user object i.e token. Client can save token using cookie, local-storage, or other mechanism. Then on every user request it validates token and proceed request.
express-jwt:
You can use it as multi-tenancy purpose like,
Validate user credentials and encrypt data like passport-jwt.
https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens
OAuth: you can create jwt token and validate using secret key.
https://auth0.com/learn/json-web-tokens/

JWT: How much I can trust to my payloads

suppose I create a jwt token for a user and set a payload as:
['userID'=>1, 'role'=>'user']
In case of using HTTPS and SSL, Is it safe to send role or any other sensitive information via payload? Is it possible for sender to manipulate payload values?
UPDATE: Now I know that JWT tokens are decodable. But because they carrying a signature, any update on the values shall invalidate the token. If you want the payload be totally encrypted, try JWE!
Claims in the payload can not be manipulated with out the key, a common example is admin=false, both the client and server can see that this user is not an admin. If the user was to try and manipulate the token (to become an admin) it would not validate correctly. This is why its critically important you validate your tokens before reading any claims from them.
However you wouldn’t normally put sensitive information (like credit card numbers) in them because the claims are not encrypted however no one should be able to access your token otherwise they would be able to take over your session.
Have a play with manipulating tokens here https://jwt.io/
JWT tokens are digitally signed by the issuer, so they cannot be modified without invalidating the signature.
HTTPS is only required to prevent the token from being stolen.

Resources