I am creating a webapp using nodejs backend and reactjs frontend with a mysql database, where each user has their own separate set of data.
I need to maintain sessions to identify users(for example, which user clicked the reset password button) whilst also implementing the logout feature (necessary).
I have read articles stating that logout with jwt defeats the purpose as it requires storing tokens on database.
I am confused whether to use cookies(way less secure) or jwt with database for maintaining sessions as I have never implemented this before.
You can use JWT , when an user is authentified, you send back the token with a refresh token, that you store in your MySQL database, to your react app.
One way to do this, I think, is to create jwt tokens, store them in cookies and then remove the cookie on logout, and hence not storing it in a database . I would still like to know other ways to do this.
Related
what's a common approach of storing user sessions with Nodejs+Express and Firebase auth? I have Android and Ios app that I'd like to use the same logic on (later web as well), so I'd get the JWT token. I'd like to use that token as authorization for requests. Also I'd like to keep the user sessio and not require them to relogin again. I am not sure how to go about this, all of the Express Session resources I've found were on topic of web and cookies. I've stumbled upon MongoConnection a library for Express that presumably stores the sessions in the MongoDb, but how does the session work with non-web requests? Can anyone help me clarify this, I am aware that I am missing the point here as there is certainly an easy way to verify incoming requests and also have a session for the user to not have to login everytime.
Preferably I'd like to have an easy way to have endpoints that require JWT token access. Besides that also have a session of sorts. There is a function to verify tokens in the Firebase Admin SDK for Nodejs but it seems really weird to have to check the token manually in every request.
I treat sessions on the backend and front end entirely separately as I predominantly make RESTful apis. On the front end you can handle sessions however you like, e.g. you can start a session when a user authenticates with firebase auth, and set the user role maybe based of attributes on the firebase auth user. Use cookies, do whatever you prefer.
Then on the backend, on every endpoint just decode the token, verify it, check that the user has access to the resource they are requesting etc. Its common to write your own middlewares so that you dont have to repeat the decoding code. For further info on this approach, this might help. Its not weird to check the token manually on every request, its common practice to guarantee the authenticity of the request. Hope this is of some help.
To sum up, treat your front end session entirely separately from the backend. On your express server on the backend, on any protected endpoint decode and verify the token to determine if the user has access to the resource.
Backend sessions with firebase are a bad idea (due to it been serverless), its better to create a stateless restful api.
Good morning/afternoon/evening!
Having recently started a little Project for myself, one of the first things I wanted to do is the Login/Authentication and permission to access different routes/Authorization.
I am currently using:
NodeJS
Express
Passport (+ Passport Local and Passport JWT)
jsonwebtoken
The goal of my Server is to receive a Stateless Authentication/Authorization System because I aim to bypass the "Single-Threaded"-Problem and use Node's Cluster Module to spawn a Process for each Thread.
I have already accomplished a basic authentication via a JSON Web Token and am currently storing only the UserID, iad and expiry date in it.
Now I was thinking about adding roles to have an "easy" check if the user was allowed into certain routes or not, but there was where my problems started.
Assuming I add roles into the token, I can easily verify if I am allowed to access that route or not using the JWTStrategy of Passport.
But what if the roles have changed within the time the Token was issued, and the time the user tries to access a route he has no more permissions to? As of now, he would probably be able to still access that route because the JWT'S receive (obviously) no instant update of the roles.
Same goes for a banned/suspended user, he would still be able to use the site as normal, until the token expires and he needs to request a new one.
This until now reflects the strategy of not querying the DB after the login anymore for user information, since the JWTs are used to store the most critical data (Not user sensitve ones though).
Invalidating the Token could easily work via JTI's (TokenID in the Token) which are stored in the Database, and once the TokenID is said to be "banned" or anything, I'd simply not let the token authenticate anymore. But this adds a database call per API call...
For Roles/Permission verification, the way I see it right now as well is that I would not get around one Database call per API call to check for user rights.
I know that there are solutions like Node-ACL or CASL, but they are either In-Memory which I can't use because I would love to not rely on Memory because I am Clustering, or even Dockerizing my Application, and I don't wanna be "only" depending on Redis or MongoDB - I'd like my application to be pretty flexible when it comes to Databases.
I also know that there are Strategies like "Refresh" and "Access" Tokens, where the Refresh Token is long-lived and the Acecss-Token is short-lived (e.g. a Expiry Date of 15 Minutes) - Is this a suitable strategy? The Ban/Suspension or RoleChange would still not be instant. I could keep the Refresh and Access Token in the Database and Invalidate the Access-Token once critical data of that user changes, and let the CLient/Website figure out that the AccessToken is gone and require a new one... But this seems like a huge overhead to me...
Summary
I am using JsonWebToken to Authenticate the user. My problem is that I am not getting around a Database Query per API Call of the User because I don't have critical info always updated in the JWT (User Banned/Suspended, Roles).
What is the best thing for me to do in this Situation?
I have a rich JS app in React running on HTTPS, and server-side I have an api in NodeJS listening for client requests. The users are not developers ; actually they barely use a computer. I want a simple login/password form (something they are familiar with) for them to authenticate.
Instead of storing the username/password client-side and include them in every api request, it is suggested to store a token. If I understand correctly, server-side in DB, this token is also stored alongside the username/password in the table of users.
What confuses me, is that this token would not be hashed (e.g. with bcrypt) like the password would. So isn't it like having a clear password in the database?
Well for sure I missed something important about tokens.
Then if anyone could lead me the path on how best to manage http basic authentication with a token in NodeJS, it would be really appreciated:)
I have a Node.js application that offers several different routes in front of MongoDB. I need to make sure that only authenticated requests can access these routes.
Ideally, I want to set it up so that a username and password comes in to the API, and in a response we give them back a token. I don't mind managing the tokens inside MongoDB myself, but I need to make sure that the token we give back can make authenticated requests. I don't want to force the user to send their credentials each time, just the token.
I've read for a few days about passport, and there's currently 307 strategies. Which strategy am I describing here?
Which strategy am I describing here?
You are describing a Local Strategy.
As per their description:
This module lets you authenticate using a username and password in your Node.js applications.
I don't want to force the user to send their credentials each time, just the token.
Passport auth strategies just provide various ways to authenticate (or in simple terms login) the user, not how to persist that login. Login persistence is usually done with user sessions.
One way you can solve this is to combine the local strategy with the express session middleware. Combination of the two allows for a fairly simple auth system that requires the user to login once and then persists the session.
In a typical web application, the credentials used to authenticate a user will only be transmitted during the login request. If authentication succeeds, a session will be established and maintained via a cookie set in the user's browser.
Each subsequent request will not contain credentials, but rather the unique cookie that identifies the session. In order to support login sessions, Passport will serialize and deserialize user instances to and from the session.
PassportJS docs give an example how to achieve this.
For this you should prefer generating JWT tokens for a the login and then using the token to always authenticate user actions.
Following steps are need to implement this style of token login system
generate token on login
verify when token supplied and use the decoded data to identify user
use should proper middleware in order to protect your api.
Here is a link you could follow:
https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens
I use a pyramid and i need logout all users from my site. Currently i cant find any place where are sessions wrote. There is nothing written in pyramid documentations about this situation so is any way to do that?
This depends on the authentication backend you're using. If the backend stores the session somewhere, you can just clear that somewhere.
If you're using a backend that stores the session in a cookie, like AuthTktAuthenticationPolicy, then the cookie is signed with a secret that present in your configuration. Changing this secret would invalidate all cookies, effectively logging out all users.
Change your session factory settings, such that request object return the session after calling its session.clear method.