I have a bunch of questions about express-session and JWT in a project that I am building.
I have an Express API server that I want to protect using some sort of API key, to make sure only authorized applications can access to my data. JWT would probably get the job done. However I also need to authenticate users and restrict them from accessing certain parts of the data (e.g. role-based permissions) using express-session.
The frontend server would be a Next.js instance, which would save and use the cookies for express-session. The session would be stored in a MongoDB instance.
Would I be able to use both authentication methods in the same project? Would it be secure? Is there any easier approach to this? How could I implement the permissions?
Any help and tips would be appreciated.
JWT and Express-Session both accomplish the same thing. The difference is a browser does not allows a http-only cookie to be accessible through javascript. At then end they are both used for the same end.
The jwt should be related to a session of a user, therefore the users permissions are the ones that matter. These can be implemented in a DBs and related to the user. Does he has this permission or does his role has this permission is the middleware you would put on the routes.
In case of doing it with express-session, I would personally take the same approach.
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.
I am planing to make a simple admin CP. Im oldschool PHP developer where usually all is in one huge monolith server and concept of microservices does not apply.
In my next app I would like to have:
Express UI (Frontend) <----> REST/GraphQL API <-----> DB server
The idea is to limit access to DB as much as possible. All requests from users would go to frontend only and API would be used only internally by other servers in my solution.
I will set up IP filters between API and DB, and likely between Frontend and API. But my concern is - say I want one admin to create a product. While this user will be authenticated on frontend using sessions, I need requests going to API to be somewhat authenticated too. Ignoring IP filters for now, do not want just about anybody to be able to send REST requests to API.
I have several ideas, please give me your opinion:
sharing express-session between API and frontend using mongodb (likely on yet another server) - I see latency issues
putting API service on same server as frontend and use redis to share sessions - kinda defeats the purpose of microservice separation
on login, generating jsonwebtoken that is always fwded between frontend and API for any user action - cookie stealing will be an issue, since i can only verify user logged in, not that he authorized certain action to be performed
on login, sending private key to admin and have him sign all requests that are fwded to API - this looks like a CPU overkill
Is there any generally used solution I am missing? Is separating frontend and API mitm overkill, or a good practice? I could easily merge the 2 and talk to DB directly from frontend, then i can manage everything with sessions just like with PHP.
Thanks for any inputs! Cheers
A more elaborate implementation of (1) is the use of a session server. The idea is to purely remove database lookup latency but not the bottleneck of session lookup in general. It acts as a caching layer. A zero coding implementation is to use something like redis or memcache as the session storage.
In general though, a cryptographic signing mechanism like JWT would be much more scalable because it involves zero I/O lookup. All you do is verify that the token is properly signed. And as long as you keep your application secret safe you're secure. You can even encode things like user roles and permissions directly in the token to completely avoid querying the database for it.
The key idea of JWT is that all the security is hidden in the backend. The front-end only echos back the token to the server as proof of authentication.
But since the front-end stores the token, it can be hijacked by javascript. One solution is to use HttpOnly cookies as the mechanism to transmit the tokens. I've even seen implementations where the main part of the token is sent in the Authorization header but the signature is sent in a HttpOnly cookie. This prevents scripts from being able to read the entire token.
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 am building a secure ReST API on a nodeJS server so that my Android application can access the data on my site. Based on reading some other posts, I've come to understand that I should use an access token. So my idea is to do the following:
1) When the user logs in on the Android app, the app sends a request to /api/login on my site, providing the username and password (this of course needs to happen over SSL to guard against eavesdropping).
2) My server validates that the username + password match, and, if so, responds with an access token.
3) The app uses this access token to make all subsequent requests to my API.
My question is should I store the access token in the database on my server? Specifically, should I store the fact that the access token is associated with that particular user? Most tutorials I looked at did not do this, but if I don't, then what is to stop a user with this access token modifying or viewing the data of another user? Don't I need to pair an access token with a user in my database?
try using this library, i did the same type of project and this life saver was my solution.
If you need to build a secure API the things are little more complicated. You need to sign the access token with a private keystore.
Would it be a option to use a authentication service like Auth0? They are generating a JWT token for you and you only need to validate this token. The API is completely stateless. You can find a lib for almost any programming language on their website.
What you want to do is exactly HTTP Sessions do.
So, I think you can just use HTTP Session functionality It's already implemented in WAS frameworks like Django, Spring etc. If NodeJS provide session functionality, Just use session functionality in the framework. If not, look up the HTTP Session library. Maybe you can find many library that treat session implementation.
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.