skip to content
logo
Table of Contents

Securing API Calls in React

API integration in React often introduces security risks such as token exposure, request interception, and misconfigured CORS policies.
This guide covers:

  • How to securely handle authentication tokens
  • Protecting API requests from interception
  • Preventing sensitive API key leaks
  • Properly configuring CORS for security

1. Do Not Store API Keys in Frontend Code

Hardcoding API keys in React exposes them to anyone who inspects the source code.

Bad: Hardcoding API Keys in Frontend

const API_KEY = "your-secret-api-key";
fetch(`https://api.example.com/data?api_key=${API_KEY}`);

Fix: Store API Keys on the Server

Move the API key to a backend and expose only public endpoints.

// Server-side (Express.js)
app.get("/data", async (req, res) => {
const response = await fetch(
`https://api.example.com/data?api_key=${process.env.API_KEY}`,
);
res.json(await response.json());
});

2. Securely Handle Authentication Tokens

Bad: Storing JWT in localStorage

localStorage.setItem("auth_token", token);

Fix: Use HTTP-Only Cookies

HTTP-only cookies prevent XSS attacks.

// Server-side (Express.js)
app.post("/login", (req, res) => {
res.cookie("auth_token", "secure-token", {
httpOnly: true,
secure: true,
sameSite: "Strict",
});
res.send("Logged in");
});

3. Prevent API Request Interception

Attackers can intercept API requests using man-in-the-middle (MITM) attacks.

Fix: Enforce HTTPS

Ensure all API requests are only over HTTPS.

const API_URL = "https://secure-api.example.com";

Fix: Use Authorization Headers Securely

Use the Authorization header with bearer tokens, not query parameters.

fetch(API_URL, {
method: "GET",
headers: { Authorization: `Bearer ${token}` },
});

4. Restrict CORS to Trusted Domains

Misconfigured CORS policies allow cross-origin API requests, making APIs vulnerable.

Bad: Allowing All Origins (*)

// Server-side (Express.js)
app.use(cors({ origin: "*" })); // Security Risk

Fix: Restrict API Access to Specific Domains

app.use(cors({ origin: ["https://yourapp.com"], credentials: true }));

5. Rate Limit API Requests

Rate limiting prevents brute-force attacks and API abuse.

// Server-side (Express.js)
import rateLimit from "express-rate-limit";
const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100 });
app.use("/api/", limiter);

6. Avoid Leaking Sensitive Data in API Responses

Bad: Returning Unfiltered User Data

res.json(user); // Returns full user object with sensitive fields

Fix: Filter Out Sensitive Data

res.json({ id: user.id, username: user.username });

Conclusion

  • Store API keys on the server, never in frontend code.
  • Use HTTP-only cookies for authentication instead of localStorage.
  • Enforce HTTPS to prevent request interception.
  • Limit API access with secure CORS configurations.
  • Rate-limit API requests to prevent abuse.

Securing API calls in React requires frontend and backend collaboration.
Following these best practices helps prevent data leaks and unauthorized access.