Securing API Calls in React
/ 2 min read
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.