Securing API Keys in Frontend Apps: A Practical Guide
APIs are the backbone of modern web apps. But every time your frontend talks to an API, there are security decisions to make. Get them wrong and you could expose API keys, leak user data, or open your app to attacks. This guide covers the most important security practices for frontend developers working with APIs.
Never expose API keys in client-side code
This is rule number one, and it gets broken constantly. If your JavaScript contains an API key, anyone can see it. Open DevTools, view source, or inspect network requests — the key is right there.
Even if you put the key in a .env file and use a bundler to inject it, the key ends up in your compiled JavaScript bundle. Environment variables in frontend frameworks like React or Vue are compiled into the client-side code at build time — they're not secret.
What to do instead
Move the API call to a backend server. Your frontend calls your server, your server calls the API with the key, and the key never touches the browser:
Many of the APIs listed on API Bouncer require no authentication at all, which eliminates this problem entirely. When choosing an API, consider whether you need one that requires a key or if a keyless alternative exists.
Build a simple proxy server
You don't need a complex backend. A minimal Express server with a few proxy endpoints is enough for most projects:
Notice how we validate the input, use encodeURIComponent(), and return generic error messages. These small details matter.
Always use HTTPS
If your app or API uses plain HTTP, anyone on the network (coffee shop Wi-Fi, ISP, corporate proxy) can read every request and response in plain text — including API keys, auth tokens, and user data.
- Only call APIs over HTTPS. If an API only offers HTTP, don't use it for anything sensitive.
- Serve your own app over HTTPS. Free TLS certificates from Let's Encrypt make this easy.
- Use
Strict-Transport-Securityheaders to prevent downgrade attacks.
Handle auth tokens safely
If your app has user authentication and you're storing tokens (JWTs, session tokens) in the browser, where you store them matters:
- HttpOnly cookies — The most secure option. The browser sends the cookie automatically, and JavaScript cannot access it (protecting against XSS attacks). Your server sets the cookie, not your frontend.
- localStorage — Convenient but vulnerable. Any JavaScript on the page (including injected scripts from XSS attacks) can read localStorage.
- sessionStorage — Slightly better than localStorage since it clears when the tab closes, but still vulnerable to XSS.
- In-memory variables — Good for short-lived tokens. They disappear on page refresh, which is sometimes acceptable.
For most apps, HttpOnly cookies are the right choice. If you must use localStorage, make sure your app has strong XSS protections.
Validate input on both sides
Never trust user input, even if you're just passing it through to an API. Validate on the frontend for user experience and on the backend for security.
Pay particular attention to values that get interpolated into URLs. Always use encodeURIComponent() to prevent injection.
Rate limiting your proxy
If you build a proxy server, add rate limiting. Without it, someone could abuse your endpoint and burn through your API quota (or rack up charges on paid APIs):
CORS configuration on your server
If your backend and frontend are on different origins, you'll need to configure CORS on your server. Be specific about allowed origins in production:
Using * as the allowed origin is fine for public APIs but not for your own backend that handles authenticated requests. For a deeper explanation, see our CORS guide.
Common mistakes to avoid
- Logging sensitive data — Don't
console.log()auth tokens or API keys, even during development. Logs end up in unexpected places. - Committing .env files — Add
.envto your.gitignoreimmediately when creating a project. Check your Git history if you've already committed one. - Trusting API responses — Sanitize data before inserting it into the DOM. An API could return HTML or scripts that cause XSS if rendered with
innerHTML. - Ignoring error responses — Don't display raw API error messages to users. They might contain internal information. Show generic messages instead.
- Using HTTP for API calls — Even if the API works over HTTP, always use HTTPS.
A security checklist
Before deploying any project that uses APIs, run through this:
- Are all API keys stored on the server, never in frontend code?
- Is every external API call made over HTTPS?
- Is user input validated before being sent to any API?
- Are auth tokens stored in HttpOnly cookies (not localStorage)?
- Does your proxy server have rate limiting?
- Are CORS origins restricted in production?
- Is your
.envfile in.gitignore?
Security is not about doing one thing perfectly. It's about layering multiple protections so that no single mistake is catastrophic. Start with the basics above and you'll be ahead of most projects out there.