Authentication in React Using JWT: Complete Tutorial — Episode 27 (Updated June 2026) (Updated June 2026)
TCS laid off 12,000 employees in July 2025 — and the developers who survived that round were the ones who could build secure, production-ready features, not just UI screens. NASSCOM and Deloitte project India needs 1.25 million AI-ready tech professionals by 2027, but "AI-ready" doesn't mean just knowing machine learning — it means being able to build and secure the APIs and applications those AI models power. Authentication is one of those fundamentals. Here's the thing: React itself doesn't handle authentication — that's the backend's job — but the React side of the auth flow is where most beginners make security mistakes. This episode covers how to implement JWT authentication in React correctly, from the login form to the protected route.
- JWT (JSON Web Token) is a compact, signed token the server issues after login — the client sends it with every subsequent request
- Store JWTs in httpOnly cookies for production — localStorage is convenient but vulnerable to XSS attacks
- Protected routes in React redirect unauthenticated users to login using a wrapper component that checks token validity
- Access tokens should be short-lived (15 min); refresh tokens allow getting new access tokens without re-login
- Correct JWT implementation is tested in virtually every full stack developer interview in India
What Is JWT and Why Does Every App Use It
JWT stands for JSON Web Token. It's a compact, URL-safe string containing three parts — header, payload, and signature — separated by dots. The header identifies the algorithm used to sign the token. The payload contains claims: the user's ID, role, email, and when the token expires. The signature is a cryptographic hash of the header and payload using the server's secret key. Because the signature is cryptographically bound to the content, a server can verify a JWT without a database lookup — it just re-hashes the received header and payload with its secret and compares. If the hashes match, the token is authentic and untampered. If they don't, the token was forged or modified. This is why JWTs are stateless and scalable — perfect for APIs that serve thousands of simultaneous requests.

The Complete Login Flow: From Form Submission to Token Storage
The login flow from a React perspective has five steps. First, the user fills in the login form and submits. Second, React makes a POST request to the backend API with the credentials. Third, the backend verifies the credentials against the database and, if valid, creates and signs a JWT containing the user's ID and role. Fourth, the backend returns the JWT (in the response body or as a Set-Cookie header). Fifth, React stores the token and updates the authenticated state, then redirects the user to the dashboard or original requested page. In React, you typically manage the authenticated state in Context API or a state management library so components across the app can check whether the user is logged in. The actual verification of the token happens on every API call, not just on login.
| Storage Method | XSS Risk | CSRF Risk | Best For |
|---|---|---|---|
| localStorage | High | Low | Learning and demos only |
| sessionStorage | High | Low | Short session, not recommended |
| httpOnly Cookie | Low | Moderate | Production apps (with CSRF protection) |
| In-Memory (React state) | Low | Low | Highest security, lost on refresh |
Storing JWT Tokens Safely: localStorage vs httpOnly Cookies
Where you store the JWT in the browser determines your security posture. Storing in localStorage is the easiest option — JavaScript can read it and attach it to every API call. The problem: any JavaScript on your page can also read it, including injected scripts from an XSS (cross-site scripting) attack. In production, use httpOnly cookies instead. These are cookies the browser sends automatically with every request to your domain, but JavaScript cannot read them — which eliminates the XSS theft risk. The tradeoff is that your backend must set the cookie with the correct domain, SameSite, and Secure flags, and your frontend loses direct access to the token value. For a production app at a company like Infosys or a funded startup, httpOnly cookies are the required approach. For learning and internal tools, localStorage is acceptable.

Implementing Protected Routes in React
Protected routes in React are components that check authentication status before rendering their children. The pattern: create a ProtectedRoute component that reads your auth context, checks for a valid token or authenticated state, and either renders the requested component or redirects to the login page using React Router's Navigate component. Wrap all pages that require authentication in ProtectedRoute in your router configuration. When a user tries to access /dashboard without being logged in, ProtectedRoute intercepts and redirects to /login, often passing the intended URL as a query parameter so after login you can redirect them back to where they wanted to go. This is the standard pattern used in every React SPA with authentication.
Refresh Tokens: Keeping Users Logged In Securely
Access tokens expire quickly — typically 15 minutes to 1 hour. Short-lived tokens limit the damage if one is stolen: the attacker only has a brief window. But making users log in every 15 minutes is terrible UX. Refresh tokens solve this: a separate, longer-lived token (7–30 days) stored in an httpOnly cookie that the client can exchange for a new access token automatically when the current one expires. The refresh endpoint checks the refresh token, verifies it against a stored record in the database, and issues a new access token. If the refresh token is expired or revoked (for example, on logout), the user must log in again. Implementing this flow correctly is what separates full stack developers who can build secure apps from those who can only build demo apps.
Common JWT Authentication Mistakes and How to Avoid Them
The most common JWT mistakes in React applications: storing tokens in localStorage in production (XSS vulnerable), not validating the token on the backend for every protected API endpoint (trusting the client), using a weak or hardcoded JWT secret (makes forging trivial), never expiring tokens (a stolen token works forever), and not implementing refresh token rotation (reuse of stolen refresh tokens). Trust me — JWT authentication mistakes are in the top three categories of security vulnerabilities at Indian IT companies discovered during security audits. Getting this right from the start means your code passes security review and you build a reputation as a developer who thinks about security, not just functionality.
Maharashtra's CMYKPY (Chief Minister Yuva Karya Prashikshan Yojana) scheme provides ₹6,000–10,000 monthly to eligible students in recognized skill training programs. If you're completing this full stack React and Node.js course at ABC Trainings, check your CMYKPY eligibility — the stipend can significantly offset your training costs while you build the skills to land a ₹4–7 LPA developer role.Get the Full Stack Development Brochure + Fees + Batch Dates on WhatsApp
Free 1:1 counselling. Placement track record. CMYKPY/PMKVY eligibility check.
💬 Get Brochure on WhatsApp📞 Call 7039169629About the author: Amit Kulkarni. 8 yrs leading IT training at ABC Trainings, ex-Infosys.
Visit Our Centers
- Wagholi (Pune): 1st Floor, Laxmi Datta Arcade, Pune-Ahilyanagar Highway. Call 7039169629
- Hadapsar (Pune HQ): 1st Floor, Shree Tower, opp. Vaibhav Theater, Magarpatta. Call 7039169629
- Cidco (Chh. Sambhajinagar): Kalpana Plaza, opp. Eiffel Tower, N-1 Cidco. Call 7039169629
- Osmanpura (Chh. Sambhajinagar): S.S.C Board to Peer Bazar Road, near Jama Masjid. Call 7039169629
- Sangli: Shubham Emphoria, 1st Floor, Above US Polo Assn., Sangli-Miraj Rd, Vishrambag. Weekend batches available. Call 7039169629
FAQs
What is the difference between authentication and authorization in web apps?
Authentication is the process of verifying who a user is — confirming their identity through credentials like email and password. Authorization is the process of determining what that verified user is allowed to do — checking their role or permissions before allowing access to a specific resource. JWT handles authentication by encoding the user's identity in a signed token. Authorization uses the claims inside the token (like role: 'admin') to decide access rights on protected endpoints or UI elements.
Can JWT tokens be used without a backend in a React-only app?
No — JWTs must be created and signed on a trusted backend using a secret key that never leaves the server. A React-only app cannot safely create JWTs because the signing secret would be exposed in client-side code. For React apps without a custom backend, use a third-party authentication service like Firebase Auth, Auth0, or Supabase Auth — they handle the JWT signing on their servers and return tokens to your React app.
How do I decode a JWT token in React to get user information?
Use the jwt-decode library (or atob with JSON.parse for a manual approach) to decode the token payload in React. The payload contains the user's ID, email, role, and expiry timestamp. Important: decoding is not verification — you're just reading the base64-encoded payload. Only the backend can verify the signature cryptographically. In React, decode to extract display information (username, role for UI logic) but never trust decoded client-side data for security decisions.
What should I do when a JWT token expires in the middle of a user session?
Handle token expiry gracefully using an Axios interceptor or fetch wrapper that detects a 401 Unauthorized response from the backend (which the backend sends when the token is expired). On 401, automatically call your refresh token endpoint to get a new access token, update storage, then retry the original failed request. If the refresh also fails (refresh token expired), redirect the user to login. This pattern creates a seamless UX where users stay logged in without manual re-authentication, while tokens remain short-lived for security.



