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.