Skip to content

JWT Authentication in React Interview Guide

JWT (JSON Web Token) is a compact, URL-safe token used for securely transmitting user information between client and server.

A JWT consists of three parts:

Header.Payload.Signature

Example:

eyJhbGciOiJIUzI1NiJ9
.
eyJzdWIiOiIxMjM0NTYifQ
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JWT is commonly used for:

  • User authentication
  • Stateless authentication
  • Secure API communication
  • Single Sign-On (SSO)
  • Microservices authentication
flowchart TD
    A[User Login] --> B[Backend validates credentials]
    B --> C[Backend generates JWT]
    C --> D[React stores JWT]
    D --> E[JWT sent with API requests]
    E --> F[Backend validates JWT]
  1. User enters username and password.
  2. React sends credentials to the backend.
  3. Backend validates the user.
  4. Backend generates a JWT.
  5. React stores the JWT.
  6. JWT is sent in the Authorization header.
  7. Backend verifies the JWT.
Authorization: Bearer eyJhbGciOi...
localStorage.setItem("token", jwtToken);

Pros

  • Easy to implement

Cons

  • Vulnerable to XSS attacks
sessionStorage.setItem("token", jwtToken);

Pros

  • Cleared when the browser tab closes

Cons

  • Still vulnerable to XSS attacks

Pros

  • Not accessible from JavaScript
  • Better security

Cons

  • Requires backend support

Production recommendation: Use HttpOnly Secure Cookies whenever possible.

axios.get("/api/users", {
headers: {
Authorization: `Bearer ${token}`
}
});
const ProtectedRoute = ({ children }) => {
const token = localStorage.getItem("token");
return token ? children : <Navigate to="/login" />;
};

Usage:

<Route
path="/dashboard"
element={
<ProtectedRoute>
<Dashboard />
</ProtectedRoute>
}
/>
  • Access Token: Short-lived (typically 15 minutes)
  • Refresh Token: Long-lived (typically 7-30 days)
flowchart TD
    A[Access Token Expired] --> B[React sends Refresh Token]
    B --> C[Backend validates Refresh Token]
    C --> D[Backend issues new Access Token]

Backend response:

401 Unauthorized

React example:

if (error.response.status === 401) {
logout();
}

Alternatively, request a new access token using the refresh token.

const payload = JSON.parse(atob(token.split('.')[1]));
const expiry = payload.exp * 1000;
if (Date.now() > expiry) {
logout();
}
jwtDecode(token);
  • Reads token contents
  • Does not verify authenticity

Performed on the backend.

Jwts.parserBuilder()
.setSigningKey(secretKey)
.build()
.parseClaimsJws(token);

Verifies:

  • Signature
  • Expiration
  • Integrity

No.

React can decode JWTs and read claims, but only the backend should verify signatures because the secret key must never be exposed to clients.

const AuthContext = createContext();

Provider:

<AuthProvider>
<App />
</AuthProvider>

Store:

  • User information
  • Login
  • Logout
  • Token
useEffect(() => {
const token = localStorage.getItem("token");
if (token) {
setIsAuthenticated(true);
}
}, []);

A refresh token mechanism is preferred in production.

Attaching and Refreshing Tokens with Axios Interceptors

Section titled “Attaching and Refreshing Tokens with Axios Interceptors”

A request interceptor attaches the token to every outgoing request, and a response interceptor can catch a 401, refresh the token, and retry the original request. See the Axios Interceptors Interview Guide for the full request/response interceptor patterns, execution order, and infinite-retry-loop prevention.

localStorage.getItem("token");

A malicious script injected through an XSS vulnerability can read the token.

Preferred:

  • HttpOnly Cookies
  • Secure Cookies
  • SameSite Cookies
JWT Session
Stateless Stateful
Highly scalable Requires server memory
Good for microservices Traditional web apps
Token stored on client Session stored on server

Securing a React + Spring Boot Application

Section titled “Securing a React + Spring Boot Application”
  • React
  • Protected Routes
  • Axios Interceptors
  • Spring Security
  • JWT Validation Filter
  • Refresh Tokens
  • Role-based Authorization
  • HTTPS
  • HttpOnly Cookies
  • CSRF Protection
  • Token Rotation

JWT payload:

{
"username": "admin",
"roles": ["ADMIN"]
}

React:

if (user.roles.includes("ADMIN")) {
return <AdminPage />;
}

The backend must always validate authorization.

Avoid trusting client-side authorization alone.

Incorrect:

if (role === "ADMIN") {
showAdminPage();
}

Correct:

  • Frontend hides or shows UI.
  • Backend validates every request.

In React applications, JWT authentication is typically implemented using access tokens and refresh tokens. Access tokens are attached through Axios interceptors, protected routes control UI access, and authentication state is managed through Context API or Redux. For enterprise applications, HttpOnly Secure Cookies are preferred over Local Storage to reduce XSS risks. Token refresh, role-based authorization, and backend validation using Spring Security JWT filters provide a secure end-to-end authentication solution.

  • JWT provides stateless authentication between React clients and backend services.
  • Prefer HttpOnly Secure Cookies over Local Storage for production security.
  • Use Axios interceptors to automatically attach and refresh tokens.
  • React should decode JWTs but never verify signatures; verification belongs on the backend.
  • Always enforce authentication and authorization on the server, regardless of frontend checks.