Implementing an HTTP Proxy for Rest API in Next.js
Wouldn’t be great if your back-end service is hidden from public users and other various malicious attacks? There is a way to empower your communication with back-end services from Next.js
Security must be one of your most important concerns when building a web application. Usually, you don’t want to expose the sensitive data of your users.
Most modern web applications authenticate with tokens. Tokens should be stored by the client to send requests after. There is plenty of way of storing a user’s token in the user’s browser. However, the most popular way to keep all types of tokens in local storage or normal cookies. Unfortunately, it’s not the safest place to store tokens.
Local storage and normal cookies both of them can be accessed from third-party scripts and browser extensions. I’ll be talking about storing the token at cookies as HttpOnly.
Why do you have to use HttpOnly cookies to store the tokens?
HttpOnly cookies can’t be accessed via client-side JavaScript code. Therefore, browser extensions and any JavaScript code that runs on the client-side cannot access those cookies. Thus, your JWT or something else is secure and safe. Finally.
Using an HTTP proxy doesn’t come just from secure cookies. It also provides security advantages — even if a cross-site scripting (XSS) flaw exists, and a user accidentally accesses a link that exploits the flaw, the browser will not reveal the cookie to the third party.
Designing API Proxy
Before we write the code I’ll share the flow with you. We are going to make two different endpoints for the BFF. The first one is only to handle login operations. The second one will be used to forward all requests to the actual API.
The flow above indicates how the login endpoint works. In fact, we can implement it all in a single point. It doesn’t make sense to keep all logic in a single file. Because of that, I’ve separated login logic to somewhere else.
Implementing API Proxy
In this step, we will add and enable the API proxy. We must create a proxy server to forward the requests to the target resource.
0. Set up environment variables
You must define some environment variables before starting. Create a file named .env
in the root directory if you don’t have one. We are going to get our back-end service URL from env variables.
Note: We shouldn’t prefix the env variable with NEXT_PUBLIC_* to avoid exposing it to the browser.
SERVICE_URL=http://localhost:8000/api
1. Install http-proxy and cookies package as a dependency
We need http-proxy
to create a proxy server and the cookies package to deal with cookies.
npm install http-proxy cookies
2. Create a proxy server
You must create a proxy server instance to use API routes. Firstly, create a folder called server
in your root directory. This folder contains all your server kinds of stuff etc. Just in case, you can set up your own custom server in this folder.
After you’ve created the server folder. Create a folder called proxy.js
in /server
directory.
3. Implement login endpoint
You have to create an endpoint to handle login operations. I assume you have an authentication service to sign in to the users. To achieve that, create a folder called api
the pages folder. This folder contains routes.
After you’ve completed these steps. You have to create a route file called login.js
in your api/auth
folder.
4. Implement API proxy
We need an entry point to forward the requests to the target resource. To do that we will create a file called [..path].js
under the api
folder that we’ve created. This route will handle all endpoints after comes /api
prefix.
That’s it. You are ready to use your proxy server. In fact, you can add some features to this implementation. I’ve also added a logout API route. I’ve prepared a demo. You can view it from Github.
Caveats
This feature comes with all disadvantages and advantages actually. Since we’re using the proxy to communicate BFF. That leads to an increase in TTFB time. Also, the setup and maintenance of a proxy server can be costly.
Thank you for reading this.