Redirect APIs calls from frontend to backend on different machines in Node

Viewed 305

I have a Node application that should run the frontend on one Docker container and the backend on another one. Both the frontend and backend are using Express. Currently I'm trying to redirect the APIs called from the client on the frontend to the backend.

Example: frontend running on 38.127.211.116 calls the api /api/get-price/toy/1 and this api should be forwarded to the backend running at 87.105.146.57.

I managed to to this using a proxy in the frontend server, I used a npm package called 'http-proxy-middleware'. At the moment my code looks like this (everthing under the path ?api is forwarded to the backend):

.use('/api', createProxyMiddleware({
    target: process.env.NODE_ENV === "prod" ? "someValue" : https://${devIpAddress}:${process.env.BACKEND_PORT}/`,
    // changeOrigin: true,
   secure: process.env.NODE_ENV === "prod" ? true : false // is it safe to have false in prod?
}))

I have a few questions because I don't fully understand which are the implications of the different approaches:

  1. Proxy vs CORS: Is it better this approach (proxy from frontend to backend) or a direct call from the frontend to the backend allowing CORS in the backend? Which are the advantages and disadvantages?

  2. secure option in the proxy: I can read from the docs: 'set secure to true/false, if you want to verify the SSL Certs'. If I always use false, also in prod, what could be the disadvantage? Will I have security issues? If yes, which one? Because with a proxy my backend address is hidden(?) but if I had only one machine every user would be able to see and call all my APIs anyway so what's the point of validating the caller?

  3. origin option in proxy: what is the advantage of enabling change origin?

  4. Authentication: a few pages of the website will require user authentication. For the APIs I think that the process will be pretty straightforward because the call will be redirected to the backend and the response will be passed back with the correct response based on the user credentials. I'm more interested in the user auth handling in the frontend. Because I'll have to provide html pages and these pages should be provided ONLY to logged users.But the DB with the credentials is in the backend so what would be the best strategy here? I was thinking to place a middleware before the code that shares the public Express folder and to send a http request to the backend when a user is requesting a a page that requires login. If the response is positive then the request will continue showing the page continue otherwise it will exit. But I'm wondering if this is the right approach. Something like:

.use("/admin", ()=>{
    // pseudo code
     const result = httpCallToBackend();
     if(!result) exit;
 }) // if positive go to next instruction - show html page
.use(express.static(process.env.STATIC_FOLDER_PATH, { extensions: ["html"] }))
1 Answers

Opinion question, so here are mine...

  1. Proxy vs CORS. Generally I would recommend direct calls from browser to APIs and use CORS as needed. Direct calls is especially important if the front end and back end servers are not co-located (as it seems in your case). By proxying you're adding extra network overhead between your servers and an extra hop for the user. There aren't a ton of reason to use the proxy unless you have some business requirements that require it.

  2. Secure. When using proxy you're communicating directly from one of your servers to another one of your servers. Some people may feel the extra security is not needed in this scenario and can set secure to false. Again, if your servers are not co-located, then I would definitely leave this on.

  3. Change origin. This is important only if you're on a multi-tenant virtual server that uses the origin to define with application to direct the call to. With containerization, this is extremely unusual as of late.

  4. Authentication. This is one reason why a proxy might be better. With a proxy you'll be able to set the authorization middleware on whatever routes need it on a single server. Personally, I don't think this is enough of a reason though. I would have the front-end server call into the back-end server to get logged-in user info and then you can do auth on both servers independently.

Related