Where can we store the JWT token securely? - node.js

1. User will do the login UserName and password.
2. If the login success then server will return JWT.
3. Now we will store the token.
4. Now for every request we will send the JWT Token for authentication on server.
My question is that Where can we store the JWT token because Local storage,Session,Cookies is not safe.

"Only the server should know the "secret" that is used to generate the JWT. If someone modifies the data contained in the JWT, the server will fail to decode it. So the server can trust any JWT that it can decode."
You don't need to store JWT token where someone can't find. And if you think if hackers get token of someone, there is a expiration date option for this.
Check this: How safe is JWT?

httpOnly cookie
It's a special kind of cookie that’s only sent in HTTP requests to the server, and it’s never accessible (both for reading or writing) from JavaScript running in the browser.
Check this:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies
You can use this Package to make your life easier if you want:
https://www.npmjs.com/package/react-cookie

Related

For user verification, you do need to store data on server side even when using JWT correct?

While I understand how jwt works for authentication, I'm trying to build registration.
Registration has a step that requires verification.
User enters the phone number
Code is sent via sms to user
User enters the code and device is verified
Since it's an API for mobile app there is no session/cookie built in.
I'm wondering if I can not implement cookie like system for mobile. And just make it work with JWT. But I don't have much experience with this.
This is my current flow:
User makes a POST request with Phone #
I respond with JWT (Time:Number)
I also send code via SMS
User sends the code via POST and JWT
Problem:
I don't know if code belongs to user or not, as I didn't save the code in DB.
I can't put into payload as it's just encoded not encrypted. (why is it not encrypted, what's the point of sending plain payload, what's even the point of JWT & didn't signed cookies already do that? they had session string encrypted so you couldn't change session string without invalidating the cookie)
JWT is overcome authentication/authorization mostly in APIs. JWT Access Token/Refresh Token is nothing but a JSON data in an encrypted form. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA. Key pair using RSA or ECDSA is more preferable as a security point of view. You can check authentication/authorization by decryption JWTs.
JWT token itself contains expiry date, so you can just configure expiration time to it. Access tokens are to check that user is authorized or not. Refresh tokens is necessary to get a new access token, generally used when the old access tokens are expired. Refresh token and Access token both expire but refresh token is long-lived compare to access tokens.
Generally developers use access token only but it is preferable to use access and refresh token both.

Authorization and authentication in nodejs

how the authorization token that is sent back after a user is authenticated is stored in browser and can be used for authorization in the same api for other routes until the token is deleted from the user's database after he logs off?
I used the postman for same. And there in the Headers section i got the authorization token as a response header. But how does this all work in a real login page in the browser?
For storing the token in browser you can use cookie or browser web storage (localStorage/sessionStorage). see this link for browser web storage. For those routes which need authorization you should send back the token in a header or cookie. this blog post may help you more.
Hello you can check this sample OAuth2 based on oauth2-server you can find the repo here: https://github.com/gerardabsi/NodeJS-OAuth2
Some intro,
The Authorization token is JWT usually and is created with some secret key at the server, the library like https://www.npmjs.com/package/jsonwebtoken is used mostly in NodeJs. One can use different strategies using Passport JS to make it more secure and open for 3rd party integration (like Google, FB etc).
Now your question,
When the user initially logs into the system using his valid credentials, the server generate a JWT token with secret key and sends it in the response header. The client side (browser) saves this token in the cookie or local storage, and for the next request sends this token in the request header. The server has the secret key and can verify the token's validation and can proceed or decline the request.
One should ideally use a token that expires in 1 hour (depends on use case) or so and not use non-expiring or long expiry tokens for security reasons.
This is roughly how it works, please let me know if any doubt.

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.

does data in jsonwebtoken are un rewritable

I'm using jsonwebtoken on my node js server and inside the jsonwebtoken i store the role of the user.
So everytime he do a request i just have to check if the required role is given in the token. But do people can change this role ?
I know everyone can see it but i guess no one can change it without my secret, right ?
Off course i m always checking the jsonwebtoken is correctly signed.
Do you think this method seems good ?
Sorry, english is not my main language
if you change the jwt data and then hash it with a different signature then you server will know its a fake token.
also make sure you use https so your tokens wont be available to sniffs.
if you store your token in a cookie make sure you put your cookie with http-only to prevent cookie highjack
also i recommend you to use csrf token to prevent csrf attacks
I guess you store the jwt in a Cookie or in LocalStorage on the client side.
So ofc, the user can delete or alter the cookie but he can't read it without your secret.
So if he tries to update the token, it will probably become corrupted and unreadable from your server side.
If the token is corrupted you'll probably want to log-out the user and redirect him to the login page.

is passport required when using JWT

Very basic question but probably I miss something very big in the big picture.
I cannot figure out whether passport.js is needed or not when using JWT auth. Most examples have it but I fail to see the need.
In my app, there is a /login route and once the user authenticates successfully ( local auth, I check user, a hash pair in the database) I create a token with user id in it, set an expiry, sign it and send it back as the cookie in the response. Then I check the req cookies, decrypt and if they contain user id and not expired, I consider the request authenticated. (also traffic is https only if it changes anything)
Am I doing something wrong here as I don't have passport etc. in the process?
No, JWT (RFC 7519) is a standard. passport.js is an implementation that uses JWT. It is not required.

Resources