Token storage is a critical security aspect. Improper storage can lead to XSS attacks.
System design context: Authentication token management is one of the most security-sensitive parts of any web application. A compromised token gives an attacker full access to the user's account. The storage method you choose determines the attack surface: localStorage is accessible to any JavaScript on the page, while HttpOnly cookies are invisible to JS entirely.
Storage options:
1. HttpOnly Cookies (recommended):
1Set-Cookie: token=eyJhbGci...; HttpOnly; Secure; SameSite=Strict; Path=/
2. In-memory (via state):
1function AuthProvider({ children }) {2 const [token, setToken] = useState(null);34 const login = async (email, password) => {5 const res = await fetch("/api/login", {6 method: "POST",7 body: JSON.stringify({ email, password }),8 });9 const data = await res.json();10 setToken(data.token); // Only in memory!11 };1213 return (14 <AuthContext.Provider value={{ token, login }}>15 {children}16 </AuthContext.Provider>17 );18}
3. localStorage (NOT recommended for tokens):
1// BAD: XSS can read it2localStorage.setItem("token", jwt);
Sending token:
1// With HttpOnly cookie — automatically (credentials: "include")2fetch("/api/data", { credentials: "include" });34// With Bearer token (in-memory)5fetch("/api/data", {6 headers: { Authorization: `Bearer ${token}` },7});
Refresh Token pattern:
1// Access token: short-lived (15 min), stored in memory2// Refresh token: long-lived (7 days), stored in HttpOnly cookie34async function fetchWithAuth(url, options) {5 let res = await fetch(url, { ...options, credentials: "include" });6 if (res.status === 401) {7 // Access token expired — refresh8 const refreshRes = await fetch("/api/refresh", { credentials: "include" });9 if (refreshRes.ok) {10 res = await fetch(url, { ...options, credentials: "include" });11 } else {12 // Refresh token also expired — redirect to login13 window.location.href = "/login";14 }15 }16 return res;17}
Security checklist:
Secure, HttpOnly, SameSite=Strict on auth cookies.