Easy ways to hide API keys

@Dallas
Thanks! I never really thought about this as a use case for SSR, but it makes perfect sense.

Vale said:
@Dallas
Thanks! I never really thought about this as a use case for SSR, but it makes perfect sense.

Yep, there are many good use cases other than ‘make the client faster.’

However, since the page is only SSR once and can’t refresh or modify the data.

@Dallas
I have a bunch of frontend projects from back in the day where I didn’t secure my API keys because I didn’t know how. Definitely gonna rewrite those someday into Nuxt apps using this approach.

There is an amazing service called Backendless. https://backendless.com/. I found this tool to be one of my favorites for creating simple ‘servers’ that only require you to write the code you need to handle the frontend requests coming in and the calls to the 3rd party API. Super awesome platform.

@Paris
Ah, very cool! This is kind of what I was hoping to find.

That is generally when you would need a backend. Vercel and Render.com are super easy to get started with.

express-http-proxy. You can modify each request and add the API key. This way, you will never expose the key on the frontend. I don’t understand what you said about environment variables. These live on the server and should never be exposed to the frontend.

There isn’t really a way to hide something on the frontend. Once it runs on a client device, whether app or browser, consider it to be public and leaked.

@Mai
This is better than nothing, but if you do it the easiest way possible, you’re still potentially letting attackers steal your API access, just via your own proxy. To be fully secure, you need to do more stuff.

@Dustin
I agree. I do not understand why you got downvoted.

You could use AWS Lambda functions with environment variables. They give you a million requests free, then it’s $0.20 per million requests after that.

You can set up rate-limiting with API Gateway and restrict to certain IP addresses using API Gateway Resource Policies.

The only way to hide the key is through a backend.

A simple lambda should do the trick. You NEED some server(less) part when you want to hide them. Anything else is just obfuscation.

Lambdas cost (pretty much) nothing and don’t need a lot of code to do what you need.

Build a simple proxy (make sure to make it only work with your domain with something like a CSRF token so that other people won’t just use the server).
You could quickly whip up one with something like Deno+Hono and deploy on Deno Deploy.

I find the easiest way is to set up a Next.js project hosted on Vercel. (Free)

Easy dynamic API routing, and your validation could be a SHA-256 encoded version with a secret key on the user’s email, and then validate that in the backend with crypto from Node.js.

Ignore everything that’s been said; just use Next.js with a server function and host it on whatever platform supports compute, whether it’s Vercel or AWS ECS/Lambda. You don’t need to worry about backend stuff as Next.js spins up routes behind the scenes for your server-side functions.

Bonus points: you can use the instrumentation hook in Next.js to automatically load the secret from a secrets manager when the server starts up.

@Zara
Yep, this is where I’ve landed as the best answer. I ended up setting up a server for my current project because I want to take the solution a little further, but if I hit a wall, SSR has gotta be the simplest way to achieve this.

So the API keys stored in an .env file in Next.js/React are exposed to end users?

Use environment variables or a .env file to store your API key on the backend. Never expose them in the frontend.

How you want to communicate with the backend is up to you. You could require login, CSRF tokens, HTTPS, and monitor API logs to check for abuse.

The most you could do frontend is obfuscation.

If it really is a static whitelist of users and it won’t grow often and is manageable, then you can set up HTTP authentication in your server without having to set up a backend. Nginx can do it; Apache is usually simpler for newer folks to use. You basically enter a list of users and hashed passwords in the site config, and then a dialog box pops up when you go to the site.

It’s not pretty, but it works, and you won’t have to set up an entire backend with a database and user authentication, or even work with any backend framework, with a static list of users and passwords. With HTTP authentication, you’re just working with a simple text file added to your web server’s config.