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
Related
I’m having trouble figuring out how to get Node.js backend tokens into React.js frontend local storage. To login a user will use their credentials though an external websites API using the Oauth2 flow, this will be the only way to login into the application.
Currently, the user clicks a button which opens a new window in the authorization URL where the user will grant privilege. Once granted, the user is redirected to the backend endpoint which goes through passport.js and gets the required access and refresh tokens sent from the external API. This is then stored in a session on the backend database. What I want, instead, is to not store a session on a database but instead implement JWT and store the user’s data in local storage. With the current flow, its just not possible to do this and I haven’t found the right documentation to work it out.
There are many websites that implement it the exact way I want but tracking down the way they do it has appeared to be a challenge in on itself.
So instead of using passport.js, which was causing a plethora of issues, I decided to implement the Oauth2 flow myself. Instead of doing ALL the work in the backend, I broke the flow into different parts.
Originally, I sent the user to the backend where they would recieve an authorization token there. This turned out to be troublesome, instead, request an authorization code on the front end. For example, send the user to the Auth path and redirect the user back the the front end once privileges have been granted. Wait at the frontend callback for a code, once obtained, send a post request to the backend with that code and any other data in the body.
When obtained at the backend, trade that code for the access token and respond to the post requst with the neccassary token and any other data that needs to be sent back e.g. profile name, picture, date of birth. You can the implementn the JWT flow and no database is required to store any session or tokens, all can be stored client side securely.
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.
First of all sorry if this subject already exists. I have problem with jwt token. I got register/login system in nodejs with mongodb. After I login (at localhost:3000/auth/login), my token is generated, but when i try to access another page (ex. localhost:3000/priv) it responds access denied. It look like the token has to pass with new request to another page, but how?
Jwt token doesn't work like cookies in the browser
You've to manually store the token to the localStorage or other storage in frontend after login & then attach that jwt token accessing from localStorage to Authorization header while requesting to another route
You can learn this entire process from https://auth0.com. They've a great tutorial on it. Also learn about access-token & refresh-token mechanism to ensure better security
I am working on deploying my Node.js app into production. We had been running into some CSRF issues but after looking deeper into the problem and learning more about CSRF attacks, I'm wondering if we even need to perform these checks.
Our API is whitelisted from our CSRF checks so our mobile apps that rely on the API can run properly (we're working on securing that currently). On the web frontend, we allow our users to register/log in and create/edit their data. We use Firebase's email/password authentication system to perform authentication (https://firebase.google.com/docs/auth/web/password-auth). As I understand it, this means we don't have to worry about CSRF attacks on registering and logging in because Firebase handles that. My question is: if we make sure our users are authenticated with Firebase on each Post route in our app, does that mean we don't have to worry about CSRF attacks?
CSRF becomes an issue when you are saving a session cookie. Firebase Auth currently persists the Auth State in web storage (localStorage/indexedDB) and are not transmitted along the requests. You are expected to run client side code to get the Firebase ID token and pass it along the request via header, or POST body, etc. On your backend, you would verify the ID token before serving restricted content or processing authenticated requests. This is why in its current form, CSRF is not a problem since Javascript is needed to get the ID token from local storage and local storage is single host origin making it not accessible from different origins.
If you plan to save the ID token in a cookie or set your own session cookie after Firebase Authentication, you should then look into guarding against CSRF attacks.
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