I'm using JWT authentication for my back-end system written with Django rest frame work,
I've read many articles about JWT security but I have some question yet,
our solution for not saving the access token in browsers local was that we save the refresh token in cookie and client request access token with this cookie in every request for not saving access token anywhere,is this approach save enough?
what can I do for server side?for example is using dynamic secret key for JWT a good idea?
I mean create an secret key for each user and use it for token.or any idea that can secure our system.
Related
I am using MEAN stack and creating a login system for it. I am trying to do Google Oauth using passport-google-oauth20 in nodejs with Angular 10 as frontend. I am also creating JWT for it. Inside Angular 10, I am directly using
window.location.href = 'http://localhost:9000/auth/google'
to call the get request of my nodes server. After google login and creating JWT, I am doing
res.redirect('http://localhost:4200/dashboard/'+encodeURI(JSON.stringify(info)))
with JWT and some user info. How can I achieve that securely? Here, I am passing it as URL parameters but I feel from security point of view that is not safe. Also, where can I securely store this JWT on the frontend for authorizing other requests?
Doing via the querystring is not going to be secure, granted the token itself should be encrypted but other elements of the token are just base64, so storing the token securely is done via a secure cookie.
Depending on your use case you can also do this as a 'runtime' variable where you store the token in memory, so each time the user refreshes the page they need to request a new token but if you want users to be able to re-use the token then you would store that in a secure cookie
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.
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.
How can you provide example for refresh node js auth token? I mean by what the parameters can I refresh auth token? For example if I can refresh it by login and password then where should I store this params for single-page app? As I understand store it in cookie is not good idea for security, localstorage is not good also because some of browsers not supported it. So maybe someone know another way for refresh token?
Cookies are a very secure storage mechanism, if used correctly. Local storage should never be used for authentication information. OWASP has a great write-up on storage security:
https://www.owasp.org/index.php/HTML5_Security_Cheat_Sheet#Storage_APIs
To quote the important parts:
Do not store session identifiers in local storage as the data is always accessible by JavaScript. Cookies can mitigate this risk using the httpOnly flag.
[With local storage] There is no way to restrict the visibility of an object to a specific path like with the attribute path of HTTP Cookies, every object is shared within an origin and protected with the Same Origin Policy. Avoid host multiple applications on the same origin, all of them would share the same localStorage object, use different subdomains instead.
Back to your original question: where to store the refresh token? Answer: In a HttpOnly cookie. This prevents the cookie from being stolen by XSS attacks, and it makes it very easy for your server to issue new access tokens (using the refresh token) because the server will have access to both at the same time, on the same request.
You can add another layer and encrypt the entire refresh token that is stored in the cookie.
Caution: when using cookies, you also need to protect yourself against CSRF attacks
I’ve written at length about front-end security and JWTs in these two blog posts:
Token Based Authentication for Single Page Apps (SPAs)
https://stormpath.com/blog/build-secure-user-interfaces-using-jwts/
Disclaimer : I work at Stormpath, our service gives you a secure, hosted user database with many features. Our express-stormpath module makes it very easy to get started with login and registration flows for your application. We are in the process of writing a new release, and it will be using access tokens in the way that I describe in this answer.
I created AuthToken model that contain these fields:
user_id, access_token, refresh_token, access_token_expiration
After successful user login, server side will send refresh_token and access_token to client side and store it to localstorage(cookies for old browsers).
And all subsequent requests will be sent with access_token(I use header x-access-token for $httpProvider in angular).
When token expires, client needs to send refresh_token for updating access_token, refresh_token and expiration date. Since I use sockets I can refresh access_token if it is expired in any request(for this I send z-refresh-token header also for each request) so I shouldn't send any extra request and I can keep current user request, just will return tokens via socket event after it was updated.
Hope this helps
I have been researching on RESTful authentication alot, and I still can't get a very clear idea, how can I design my web architecture. I have many questions that are unanswered.
I want my API to be served to mobile and web too and I am using Express v4.
I don't want to use Basic Authentication, as many posts have suggested as a simple way out, or I can use the Passport middleware, but I want to use token based authentication or something similar or better,and I want to make my authentication, so I could understand better, but I am not sure how can I achieve it.
I will simplify my intended authentication architecture below:
Registration of a new user
Client side
Post username and password to server
(I know if you want to make the connection secured is to use https connection, or else I will expose my credentials, or you got any other options besides https? or else I will need to use the public and private key with timestamp and hash my credentials before sending to server? How can i do this? Is there any other better option?
Server side
Hashed the password using salt cryptography, and stored the hashed password and salt, then generate a token ID and sent to the client, and the token ID is stored in sessions or using the REDIS database?
Isn't that using sessions violates REST again? But, if I don't use sessions, how can I store the token ID and compare it with the client side?
Client side
Since now I have the token ID, how can I store on client side?
Should I use cookie? If yes, will this violate the RESTful? And how can my mobile application store the cookie too?
What other options can I have besides cookie? I can't think of any.
Authorizing API
Client side
Now, I have the token ID, I will place this in the authorization header each time I would like to make a request to the server.
Server side
When a request is received, the server will check the token API, and compare it with the session token, if it is true, request allow else reject
Is this a standard way for Express application authorization?
I am sorry for the lengthy post, but I feel that I should really master the authentication and authorization because it is important. I do hope someone can correct my misconception of REST authentication and answer my questions or suggest me a better way to do it.
Send the user credentials encoded over https
To compare the token at the client side you can either keep it in map or in Redis store corresponding to user id and match it to consider user authenticated. It does not kills the significance of Rest as in Rest as well authorization tokens are sessions only which after expiry
Express does not have any specific or standard method of authorization , it only enables you to use any db in backend to perform authentication and authorization as required by your application
Your solution is the use JWT tokens for your authentication .You can read more about JWT at https://medium.com/dev-bits/a-guide-for-adding-jwt-token-based-authentication-to-your-single-page-nodejs-applications-c403f7cf04f4
With JWT tokens you can have a token base auth system with no sessions UID at cookies , but you have to implement logic to handle tokens that have sign out something like blacklist tokens.