đ¯ Authentication Kya Hai?
Authentication ek process hai jisme hum verify karte hain ki user kaun hai. Jab aap kisi website pe login karte ho, toh wo authentication hai.
Authorization ye decide karta hai ki authenticated user ko kya karne ki permission hai.
- đ Authentication: "Tum kaun ho?" (Identity verification)
- đĒ Authorization: "Tumhe kya karne ki permission hai?" (Access control)
Authentication Definition
Authentication is the process of verifying the identity of a user, device, or system. It ensures that the entity requesting access is who they claim to be.
Authorization is the process of determining what permissions an authenticated user has and what resources they can access.
Authentication Methods
đ Common Authentication Methods:
- Session-based: Server pe session store hota hai
- Token-based (JWT): Client pe token store hota hai
- OAuth: Third-party providers (Google, Facebook)
- Multi-factor (MFA): Multiple verification steps
- Biometric: Fingerprint, Face ID
Why Authentication is Important?
- đĄī¸ Security: Unauthorized access se bachata hai
- đ¤ Personalization: User-specific content dikhata hai
- đ Data Protection: Sensitive data ko protect karta hai
- đ Audit Trail: Kon kya kar raha hai track karta hai
- âī¸ Compliance: Legal requirements fulfill karta hai
đĢ JWT Authentication
JWT (JSON Web Token) ek compact aur self-contained token hai jo user ki identity aur claims ko securely transmit karta hai. Ye teen parts mein divided hota hai:
JWT Definition
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed.
JWT Structure
Header
Algorithm & Token Type
Payload
User Data & Claims
Signature
Verification Hash
// JWT Example
// Header (Base64 encoded)
{
"alg": "HS256",
"typ": "JWT"
}
// Payload (Base64 encoded)
{
"sub": "1234567890",
"name": "John Doe",
"email": "john@example.com",
"iat": 1516239022,
"exp": 1516242622
}
// Signature
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
// Final JWT Token:
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiZW1haWwiOiJqb2huQGV4YW1wbGUuY29tIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1MTYyNDI2MjJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
JWT ke Important Claims:
- iss (Issuer): Token kisne issue kiya
- sub (Subject): User ka unique identifier
- aud (Audience): Token kis ke liye hai
- exp (Expiration): Token kab expire hoga
- iat (Issued At): Token kab issue hua
- nbf (Not Before): Token kab se valid hai
JWT Implementation
// Backend - Creating JWT (Node.js)
const jwt = require('jsonwebtoken');
// Login endpoint
app.post('/api/login', async (req, res) => {
const { email, password } = req.body;
// Verify user credentials
const user = await User.findOne({ email });
if (!user || !await bcrypt.compare(password, user.password)) {
return res.status(401).json({ error: 'Invalid credentials' });
}
// Create JWT token
const token = jwt.sign(
{
userId: user._id,
email: user.email,
role: user.role
},
process.env.JWT_SECRET,
{ expiresIn: '1h' }
);
res.json({ token, user: { id: user._id, email: user.email } });
});
// Middleware to verify JWT
const authenticateToken = (req, res, next) => {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (!token) {
return res.status(401).json({ error: 'Access token required' });
}
jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
if (err) {
return res.status(403).json({ error: 'Invalid token' });
}
req.user = user;
next();
});
};
// Protected route
app.get('/api/profile', authenticateToken, (req, res) => {
res.json({ user: req.user });
});
// Frontend - Using JWT (React)
import axios from 'axios';
// Login function
const login = async (email, password) => {
try {
const response = await axios.post('/api/login', { email, password });
const { token, user } = response.data;
// Store token in localStorage
localStorage.setItem('token', token);
localStorage.setItem('user', JSON.stringify(user));
return { success: true, user };
} catch (error) {
return { success: false, error: error.response.data.error };
}
};
// Axios interceptor to add token to requests
axios.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
// Fetch protected data
const fetchProfile = async () => {
try {
const response = await axios.get('/api/profile');
return response.data;
} catch (error) {
if (error.response.status === 401) {
// Token expired or invalid
localStorage.removeItem('token');
window.location.href = '/login';
}
}
};
User Information
Generated Token
â JWT Advantages
- Stateless - Server pe session store nahi karna
- Scalable - Multiple servers ke saath easy
- Cross-domain - Different domains pe kaam karta hai
- Mobile-friendly - Apps ke liye perfect
- Self-contained - Sab info token mein hai
â JWT Disadvantages
- Token size bada ho sakta hai
- Revoke karna mushkil (logout issue)
- XSS attacks ka risk (if stored in localStorage)
- Token theft ho sakta hai
- Sensitive data token mein nahi dalna chahiye
đž Storage Options
Authentication tokens ko store karne ke teen main options hain. Har ek ke apne advantages aur disadvantages hain:
đĻ LocalStorage
Browser storage jo persist karta hai
đĒ Cookies
Server aur client dono access kar sakte hain
đ HttpOnly Cookies
JavaScript se access nahi ho sakta (secure)
Detailed Comparison
| Feature | LocalStorage | Cookies | HttpOnly Cookies |
|---|---|---|---|
| Capacity | ~5-10 MB | ~4 KB per cookie | ~4 KB per cookie |
| Accessibility | JavaScript only | JavaScript & Server | Server only |
| Expiration | Never (manual clear) | Configurable | Configurable |
| Sent with Requests | No (manual) | Yes (automatic) | Yes (automatic) |
| XSS Protection | â Vulnerable | â Vulnerable | â Protected |
| CSRF Protection | â Not vulnerable | â Vulnerable | â Vulnerable (needs CSRF token) |
| Best For | SPA, Mobile apps | Traditional web apps | Secure authentication |
đ Security Best Practices:
- HttpOnly Cookies: XSS attacks se bachne ke liye best option
- Secure Flag: HTTPS pe hi cookies send ho
- SameSite: CSRF attacks se protection
- Short Expiry: Tokens ko jaldi expire karo
- Refresh Tokens: Long-lived sessions ke liye use karo
// LocalStorage Implementation
// Storing token
localStorage.setItem('token', jwtToken);
// Retrieving token
const token = localStorage.getItem('token');
// Removing token (logout)
localStorage.removeItem('token');
// Adding to axios headers
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
// ============================================
// Cookie Implementation (Frontend)
// Setting cookie
document.cookie = `token=${jwtToken}; max-age=3600; path=/; secure; samesite=strict`;
// Reading cookie
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
// Deleting cookie
document.cookie = 'token=; max-age=0; path=/';
// ============================================
// HttpOnly Cookie Implementation (Backend)
// Setting HttpOnly cookie
app.post('/api/login', async (req, res) => {
// ... verify credentials ...
const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET);
res.cookie('token', token, {
httpOnly: true, // JavaScript se access nahi ho sakta
secure: true, // Only HTTPS
sameSite: 'strict', // CSRF protection
maxAge: 3600000 // 1 hour
});
res.json({ success: true });
});
// Reading HttpOnly cookie
app.get('/api/profile', (req, res) => {
const token = req.cookies.token;
// ... verify token ...
});
đ¯ Which One to Choose?
- HttpOnly Cookies: Most secure option for web applications
- LocalStorage: Good for SPAs and mobile apps (with proper XSS protection)
- Regular Cookies: Avoid for sensitive tokens (XSS vulnerable)
đ Authentication Flow
Authentication flow mein teen main operations hote hain: Signup, Login, aur Logout. Chaliye inhe detail mein samajhte hain:
1. Signup Flow
User Form
Email, Password enter karta hai
Validation
Frontend validation
API Call
POST /api/signup
Hash Password
bcrypt se hash
Save User
Database mein store
Generate JWT
Token create karo
Send Response
Token + User data
// Signup Implementation
// Backend (Node.js + Express)
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
app.post('/api/signup', async (req, res) => {
try {
const { email, password, name } = req.body;
// 1. Validate input
if (!email || !password || !name) {
return res.status(400).json({ error: 'All fields required' });
}
// 2. Check if user already exists
const existingUser = await User.findOne({ email });
if (existingUser) {
return res.status(409).json({ error: 'User already exists' });
}
// 3. Hash password
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(password, saltRounds);
// 4. Create user
const user = new User({
email,
password: hashedPassword,
name
});
await user.save();
// 5. Generate JWT
const token = jwt.sign(
{ userId: user._id, email: user.email },
process.env.JWT_SECRET,
{ expiresIn: '7d' }
);
// 6. Send response
res.status(201).json({
token,
user: {
id: user._id,
email: user.email,
name: user.name
}
});
} catch (error) {
res.status(500).json({ error: 'Server error' });
}
});
// Frontend (React)
const signup = async (formData) => {
try {
const response = await axios.post('/api/signup', formData);
const { token, user } = response.data;
// Store token
localStorage.setItem('token', token);
localStorage.setItem('user', JSON.stringify(user));
// Redirect to dashboard
navigate('/dashboard');
} catch (error) {
setError(error.response.data.error);
}
};
2. Login Flow
User Credentials
Email, Password
API Call
POST /api/login
Find User
Database query
Verify Password
bcrypt.compare()
Generate JWT
Create token
Send Token
Return to client
// Login Implementation
// Backend
app.post('/api/login', async (req, res) => {
try {
const { email, password } = req.body;
// 1. Find user
const user = await User.findOne({ email });
if (!user) {
return res.status(401).json({ error: 'Invalid credentials' });
}
// 2. Verify password
const isValidPassword = await bcrypt.compare(password, user.password);
if (!isValidPassword) {
return res.status(401).json({ error: 'Invalid credentials' });
}
// 3. Generate tokens
const accessToken = jwt.sign(
{ userId: user._id, email: user.email },
process.env.JWT_SECRET,
{ expiresIn: '15m' }
);
const refreshToken = jwt.sign(
{ userId: user._id },
process.env.REFRESH_TOKEN_SECRET,
{ expiresIn: '7d' }
);
// 4. Store refresh token in database
user.refreshToken = refreshToken;
await user.save();
// 5. Send response
res.json({
accessToken,
refreshToken,
user: {
id: user._id,
email: user.email,
name: user.name
}
});
} catch (error) {
res.status(500).json({ error: 'Server error' });
}
});
// Frontend
const login = async (email, password) => {
try {
const response = await axios.post('/api/login', { email, password });
const { accessToken, refreshToken, user } = response.data;
localStorage.setItem('accessToken', accessToken);
localStorage.setItem('refreshToken', refreshToken);
localStorage.setItem('user', JSON.stringify(user));
navigate('/dashboard');
} catch (error) {
setError(error.response.data.error);
}
};
3. Logout Flow
User Clicks Logout
Logout button
API Call
POST /api/logout
Invalidate Token
Remove from DB
Clear Client Storage
Remove tokens
Redirect
Go to login page
// Logout Implementation
// Backend
app.post('/api/logout', authenticateToken, async (req, res) => {
try {
const userId = req.user.userId;
// Remove refresh token from database
await User.findByIdAndUpdate(userId, { refreshToken: null });
res.json({ message: 'Logged out successfully' });
} catch (error) {
res.status(500).json({ error: 'Server error' });
}
});
// Frontend
const logout = async () => {
try {
await axios.post('/api/logout');
// Clear all stored data
localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');
localStorage.removeItem('user');
// Redirect to login
navigate('/login');
} catch (error) {
console.error('Logout error:', error);
}
};
Login Form
Authentication Status
đĄī¸ Protected Routes
Protected Routes wo routes hain jo sirf authenticated users access kar sakte hain. Agar user logged in nahi hai, toh use login page pe redirect kar diya jata hai.
Protected Routes Definition
Protected Routes are routes in an application that require authentication before access is granted. They ensure that only authorized users can view certain pages or perform specific actions.
React Router Implementation
// ProtectedRoute Component
import { Navigate } from 'react-router-dom';
const ProtectedRoute = ({ children }) => {
const token = localStorage.getItem('accessToken');
if (!token) {
// User not authenticated, redirect to login
return <Navigate to="/login" replace />;
}
// User authenticated, render the protected component
return children;
};
// Usage in App.js
import { BrowserRouter, Routes, Route } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Routes>
{/* Public routes */}
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
{/* Protected routes */}
<Route
path="/dashboard"
element={
<ProtectedRoute>
<Dashboard />
</ProtectedRoute>
}
/>
<Route
path="/profile"
element={
<ProtectedRoute>
<Profile />
</ProtectedRoute>
}
/>
<Route
path="/settings"
element={
<ProtectedRoute>
<Settings />
</ProtectedRoute>
}
/>
</Routes>
</BrowserRouter>
);
}
Advanced Protected Route with Role-Based Access
// Advanced ProtectedRoute with roles
const ProtectedRoute = ({ children, requiredRole }) => {
const token = localStorage.getItem('accessToken');
const user = JSON.parse(localStorage.getItem('user') || '{}');
// Check if user is authenticated
if (!token) {
return <Navigate to="/login" replace />;
}
// Check if user has required role
if (requiredRole && user.role !== requiredRole) {
return <Navigate to="/unauthorized" replace />;
}
return children;
};
// Usage with roles
<Route
path="/admin"
element={
<ProtectedRoute requiredRole="admin">
<AdminPanel />
</ProtectedRoute>
}
/>
<Route
path="/moderator"
element={
<ProtectedRoute requiredRole="moderator">
<ModeratorPanel />
</ProtectedRoute>
}
/>
Context-Based Authentication
// AuthContext.js
import { createContext, useContext, useState, useEffect } from 'react';
const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
// Check if user is logged in on mount
const token = localStorage.getItem('accessToken');
const userData = localStorage.getItem('user');
if (token && userData) {
setUser(JSON.parse(userData));
}
setLoading(false);
}, []);
const login = async (email, password) => {
const response = await axios.post('/api/login', { email, password });
const { accessToken, user } = response.data;
localStorage.setItem('accessToken', accessToken);
localStorage.setItem('user', JSON.stringify(user));
setUser(user);
};
const logout = () => {
localStorage.removeItem('accessToken');
localStorage.removeItem('user');
setUser(null);
};
return (
<AuthContext.Provider value={{ user, login, logout, loading }}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => useContext(AuthContext);
// ProtectedRoute using Context
const ProtectedRoute = ({ children }) => {
const { user, loading } = useAuth();
if (loading) {
return <div>Loading...</div>;
}
if (!user) {
return <Navigate to="/login" replace />;
}
return children;
};
đ¯ Best Practices for Protected Routes:
- Token Validation: Har request pe token verify karo
- Loading States: Authentication check hone tak loading dikhao
- Redirect Logic: Login ke baad original page pe redirect karo
- Role-Based Access: Different roles ke liye different access
- Error Handling: Token expire hone pe gracefully handle karo
đ Refresh Tokens
Refresh Tokens long-lived tokens hote hain jo new access tokens generate karne ke liye use hote hain. Ye security aur user experience dono ko balance karte hain.
Refresh Token Definition
Refresh Token is a long-lived token used to obtain new access tokens without requiring the user to log in again. It provides a balance between security (short-lived access tokens) and user experience (no frequent logins).
Why Use Refresh Tokens?
đ¯ Benefits:
- Security: Access tokens short-lived hote hain (15 min)
- User Experience: User ko baar-baar login nahi karna padta
- Revocation: Refresh tokens ko easily revoke kar sakte hain
- Session Management: Long sessions maintain kar sakte hain
Token Flow Diagram
Login
Access + Refresh Token milta hai
API Calls
Access Token use karo
Token Expires
401 Unauthorized
Refresh Request
Refresh Token bhejo
New Access Token
Naya token milta hai
Retry Request
Original request retry
// Backend - Refresh Token Implementation
app.post('/api/refresh', async (req, res) => {
try {
const { refreshToken } = req.body;
if (!refreshToken) {
return res.status(401).json({ error: 'Refresh token required' });
}
// Verify refresh token
const decoded = jwt.verify(refreshToken, process.env.REFRESH_TOKEN_SECRET);
// Find user and check if refresh token matches
const user = await User.findById(decoded.userId);
if (!user || user.refreshToken !== refreshToken) {
return res.status(403).json({ error: 'Invalid refresh token' });
}
// Generate new access token
const newAccessToken = jwt.sign(
{ userId: user._id, email: user.email },
process.env.JWT_SECRET,
{ expiresIn: '15m' }
);
res.json({ accessToken: newAccessToken });
} catch (error) {
res.status(403).json({ error: 'Invalid refresh token' });
}
});
// Optional: Rotate refresh token for extra security
app.post('/api/refresh-rotate', async (req, res) => {
try {
const { refreshToken } = req.body;
// Verify old refresh token
const decoded = jwt.verify(refreshToken, process.env.REFRESH_TOKEN_SECRET);
const user = await User.findById(decoded.userId);
if (!user || user.refreshToken !== refreshToken) {
return res.status(403).json({ error: 'Invalid refresh token' });
}
// Generate new access token
const newAccessToken = jwt.sign(
{ userId: user._id, email: user.email },
process.env.JWT_SECRET,
{ expiresIn: '15m' }
);
// Generate new refresh token
const newRefreshToken = jwt.sign(
{ userId: user._id },
process.env.REFRESH_TOKEN_SECRET,
{ expiresIn: '7d' }
);
// Update refresh token in database
user.refreshToken = newRefreshToken;
await user.save();
res.json({
accessToken: newAccessToken,
refreshToken: newRefreshToken
});
} catch (error) {
res.status(403).json({ error: 'Invalid refresh token' });
}
});
// Frontend - Axios Interceptor for Auto Refresh
import axios from 'axios';
let isRefreshing = false;
let failedQueue = [];
const processQueue = (error, token = null) => {
failedQueue.forEach(prom => {
if (error) {
prom.reject(error);
} else {
prom.resolve(token);
}
});
failedQueue = [];
};
// Response interceptor
axios.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config;
// If error is 401 and we haven't tried to refresh yet
if (error.response?.status === 401 && !originalRequest._retry) {
if (isRefreshing) {
// If already refreshing, queue this request
return new Promise((resolve, reject) => {
failedQueue.push({ resolve, reject });
})
.then(token => {
originalRequest.headers['Authorization'] = 'Bearer ' + token;
return axios(originalRequest);
})
.catch(err => Promise.reject(err));
}
originalRequest._retry = true;
isRefreshing = true;
const refreshToken = localStorage.getItem('refreshToken');
if (!refreshToken) {
// No refresh token, redirect to login
window.location.href = '/login';
return Promise.reject(error);
}
try {
// Request new access token
const response = await axios.post('/api/refresh', { refreshToken });
const { accessToken } = response.data;
// Update stored token
localStorage.setItem('accessToken', accessToken);
// Update axios default header
axios.defaults.headers.common['Authorization'] = 'Bearer ' + accessToken;
// Process queued requests
processQueue(null, accessToken);
// Retry original request
originalRequest.headers['Authorization'] = 'Bearer ' + accessToken;
return axios(originalRequest);
} catch (refreshError) {
// Refresh failed, logout user
processQueue(refreshError, null);
localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');
window.location.href = '/login';
return Promise.reject(refreshError);
} finally {
isRefreshing = false;
}
}
return Promise.reject(error);
}
);
// Request interceptor to add token
axios.interceptors.request.use(
(config) => {
const token = localStorage.getItem('accessToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
đ Refresh Token Best Practices:
- Short Access Tokens: 15-30 minutes expiry
- Long Refresh Tokens: 7-30 days expiry
- Secure Storage: HttpOnly cookies mein store karo
- Token Rotation: Har refresh pe naya refresh token do
- Revocation: Logout pe refresh token invalidate karo
- Single Use: Ek refresh token sirf ek baar use ho
đ Authentication Providers
Authentication providers third-party services hain jo authentication ko handle karte hain. Ye implementation ko easy aur secure banate hain.
Popular Auth Providers
đĨ Firebase Auth
Google ka authentication service
- Email/Password
- Social Login
- Phone Auth
- Anonymous Auth
đ Auth0
Enterprise-grade authentication
- Universal Login
- MFA Support
- Social Connections
- Enterprise SSO
đ Clerk
Modern authentication for React
- Pre-built UI
- User Management
- Organizations
- Easy Integration
Firebase Authentication
// Firebase Setup
import { initializeApp } from 'firebase/app';
import {
getAuth,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut,
onAuthStateChanged,
GoogleAuthProvider,
signInWithPopup
} from 'firebase/auth';
// Firebase config
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_AUTH_DOMAIN",
projectId: "YOUR_PROJECT_ID",
// ... other config
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
// Sign Up
const signUp = async (email, password) => {
try {
const userCredential = await createUserWithEmailAndPassword(
auth,
email,
password
);
const user = userCredential.user;
console.log('User created:', user);
} catch (error) {
console.error('Error:', error.message);
}
};
// Sign In
const signIn = async (email, password) => {
try {
const userCredential = await signInWithEmailAndPassword(
auth,
email,
password
);
const user = userCredential.user;
console.log('User signed in:', user);
} catch (error) {
console.error('Error:', error.message);
}
};
// Sign Out
const logout = async () => {
try {
await signOut(auth);
console.log('User signed out');
} catch (error) {
console.error('Error:', error.message);
}
};
// Google Sign In
const signInWithGoogle = async () => {
const provider = new GoogleAuthProvider();
try {
const result = await signInWithPopup(auth, provider);
const user = result.user;
console.log('Google user:', user);
} catch (error) {
console.error('Error:', error.message);
}
};
// Auth State Observer
onAuthStateChanged(auth, (user) => {
if (user) {
console.log('User is signed in:', user);
} else {
console.log('User is signed out');
}
});
// React Component Example
import { useState, useEffect } from 'react';
function App() {
const [user, setUser] = useState(null);
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
setUser(currentUser);
});
return () => unsubscribe();
}, []);
return (
<div>
{user ? (
<div>
<p>Welcome, {user.email}</p>
<button onClick={logout}>Logout</button>
</div>
) : (
<div>
<button onClick={() => signIn('user@example.com', 'password')}>
Login
</button>
<button onClick={signInWithGoogle}>
Sign in with Google
</button>
</div>
)}
</div>
);
}
Auth0 Implementation
// Auth0 Setup
import { Auth0Provider, useAuth0 } from '@auth0/auth0-react';
// Wrap your app with Auth0Provider
function App() {
return (
<Auth0Provider
domain="YOUR_DOMAIN.auth0.com"
clientId="YOUR_CLIENT_ID"
redirectUri={window.location.origin}
>
<MyApp />
</Auth0Provider>
);
}
// Login Component
function LoginButton() {
const { loginWithRedirect } = useAuth0();
return (
<button onClick={() => loginWithRedirect()}>
Log In
</button>
);
}
// Logout Component
function LogoutButton() {
const { logout } = useAuth0();
return (
<button onClick={() => logout({ returnTo: window.location.origin })}>
Log Out
</button>
);
}
// Profile Component
function Profile() {
const { user, isAuthenticated, isLoading } = useAuth0();
if (isLoading) {
return <div>Loading...</div>;
}
if (!isAuthenticated) {
return <div>Not authenticated</div>;
}
return (
<div>
<img src={user.picture} alt={user.name} />
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
);
}
// Protected Route with Auth0
import { withAuthenticationRequired } from '@auth0/auth0-react';
const ProtectedRoute = ({ component, ...args }) => {
const Component = withAuthenticationRequired(component, {
onRedirecting: () => <div>Loading...</div>,
});
return <Component {...args} />;
};
// Usage
<Route
path="/dashboard"
element={<ProtectedRoute component={Dashboard} />}
/>
â Auth Providers ke Fayde
- Quick implementation
- Security best practices built-in
- Social login easy
- MFA support
- User management dashboard
- Scalable infrastructure
â Limitations
- Third-party dependency
- Cost for large scale
- Less customization
- Vendor lock-in
- Learning curve
đ¯ Kab Kaunsa Use Karein?
- Firebase: Quick prototypes, mobile apps, Google ecosystem
- Auth0: Enterprise apps, complex requirements, compliance
- Custom JWT: Full control, specific requirements, learning
- Clerk: Modern React apps, easy integration, good DX
đ¯ Interview Questions
Answer:
JWT (JSON Web Token) ek compact, self-contained token hai jo user ki identity aur claims ko securely transmit karta hai.
Structure:
- Header: Algorithm aur token type (Base64 encoded)
- Payload: User data aur claims (Base64 encoded)
- Signature: Verification ke liye hash (HMAC/RSA)
Working:
- User login karta hai
- Server JWT token generate karta hai
- Client token ko store karta hai (localStorage/cookie)
- Har request mein token bhejta hai (Authorization header)
- Server token verify karta hai aur access deta hai
Benefits: Stateless, scalable, cross-domain support
Answer:
LocalStorage:
- Capacity: ~5-10 MB
- JavaScript se access ho sakta hai
- XSS attacks ke liye vulnerable
- Manually requests mein add karna padta hai
- Best for: SPAs, non-sensitive data
Cookies:
- Capacity: ~4 KB per cookie
- JavaScript aur server dono access kar sakte hain
- Automatically requests ke saath send hote hain
- XSS aur CSRF dono ke liye vulnerable
- Expiration set kar sakte hain
HttpOnly Cookies:
- JavaScript se access NAHI ho sakta
- XSS attacks se protected
- Server-side only access
- CSRF protection ke liye SameSite flag use karo
- Best for: Authentication tokens (most secure)
Recommendation: Authentication ke liye HttpOnly Cookies sabse secure option hai.
Answer:
Protected Routes implement karne ke multiple ways hain:
Method 1: Simple ProtectedRoute Component
const ProtectedRoute = ({ children }) => {
const token = localStorage.getItem('token');
if (!token) {
return <Navigate to="/login" replace />;
}
return children;
};
// Usage
<Route
path="/dashboard"
element={
<ProtectedRoute>
<Dashboard />
</ProtectedRoute>
}
/>
Method 2: Context-Based (Better)
const ProtectedRoute = ({ children }) => {
const { user, loading } = useAuth();
if (loading) return <Loading />;
if (!user) return <Navigate to="/login" />;
return children;
};
Method 3: Role-Based Access
const ProtectedRoute = ({ children, requiredRole }) => {
const { user } = useAuth();
if (!user) return <Navigate to="/login" />;
if (requiredRole && user.role !== requiredRole) {
return <Navigate to="/unauthorized" />;
}
return children;
};
Key Points:
- Token validation zaroori hai
- Loading state handle karo
- Redirect logic proper rakho
- Role-based access implement karo if needed
Answer:
Refresh Tokens long-lived tokens hote hain jo new access tokens generate karne ke liye use hote hain.
Why Use Refresh Tokens?
- Security: Access tokens short-lived (15 min) - agar steal ho jaye toh limited damage
- User Experience: User ko baar-baar login nahi karna padta
- Revocation: Refresh tokens ko database mein store karke easily revoke kar sakte hain
- Session Management: Long sessions maintain kar sakte hain securely
Flow:
- Login pe dono tokens milte hain (access + refresh)
- Access token se API calls karo
- Access token expire hone pe 401 error
- Refresh token se new access token request karo
- New access token se original request retry karo
Implementation Tips:
- Access token: 15-30 minutes
- Refresh token: 7-30 days
- Refresh tokens ko HttpOnly cookies mein store karo
- Token rotation implement karo (har refresh pe naya refresh token)
- Axios interceptor use karo automatic refresh ke liye
Answer:
XSS (Cross-Site Scripting):
- Attacker malicious JavaScript inject karta hai
- LocalStorage/Cookies se tokens chura sakta hai
- User ke behalf pe actions perform kar sakta hai
XSS Prevention:
- HttpOnly cookies use karo (JavaScript access nahi)
- Input sanitization karo
- Content Security Policy (CSP) headers use karo
- React automatically escapes content (safe by default)
- dangerouslySetInnerHTML se bacho
CSRF (Cross-Site Request Forgery):
- Attacker user ke behalf pe unauthorized requests bhejta hai
- Cookies automatically send hote hain (browser behavior)
- User logged in hai toh attack successful ho sakta hai
CSRF Prevention:
- SameSite cookie attribute use karo (SameSite=Strict/Lax)
- CSRF tokens use karo (unique token har request mein)
- Custom headers check karo (X-Requested-With)
- Origin/Referer headers verify karo
- LocalStorage use karo (CSRF se safe, but XSS vulnerable)
// CSRF Token Implementation
// Backend
app.use(csrf());
app.get('/api/csrf-token', (req, res) => {
res.json({ csrfToken: req.csrfToken() });
});
// Frontend
const csrfToken = await fetch('/api/csrf-token').then(r => r.json());
axios.defaults.headers.common['X-CSRF-Token'] = csrfToken;
// Cookie with SameSite
res.cookie('token', jwt, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
Answer:
Session-Based Authentication:
- Server pe session store hota hai (memory/database/Redis)
- Client ko session ID milta hai (cookie mein)
- Har request pe server session verify karta hai
- Stateful - server ko session track karna padta hai
Token-Based Authentication (JWT):
- Server token generate karta hai
- Client token store karta hai
- Token self-contained hai (sab info token mein)
- Stateless - server ko kuch store nahi karna
Comparison:
| Feature | Session-Based | Token-Based |
|---|---|---|
| Storage | Server-side | Client-side |
| Scalability | Difficult (session sync) | Easy (stateless) |
| Revocation | Easy (delete session) | Difficult (token valid until expiry) |
| Mobile Apps | Complex | Easy |
| Cross-Domain | Difficult | Easy |
When to Use:
- Session-Based: Traditional web apps, need instant revocation
- Token-Based: SPAs, mobile apps, microservices, APIs
Answer:
OAuth 2.0 ek authorization framework hai jo third-party applications ko user ke resources access karne ki permission deta hai bina password share kiye.
Key Concepts:
- Resource Owner: User (jo data ka owner hai)
- Client: Application (jo access chahta hai)
- Authorization Server: OAuth provider (Google, Facebook)
- Resource Server: API server (jahan data hai)
OAuth Flow:
- User "Login with Google" click karta hai
- Redirect to Google authorization page
- User permission deta hai
- Google authorization code return karta hai
- App code ko access token ke liye exchange karta hai
- Access token se user info fetch karo
- User ko login kar do
Implementation Example (Google):
// Backend (Node.js)
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: "/auth/google/callback"
},
async (accessToken, refreshToken, profile, done) => {
// Find or create user
let user = await User.findOne({ googleId: profile.id });
if (!user) {
user = await User.create({
googleId: profile.id,
email: profile.emails[0].value,
name: profile.displayName
});
}
return done(null, user);
}
));
// Routes
app.get('/auth/google',
passport.authenticate('google', { scope: ['profile', 'email'] })
);
app.get('/auth/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
(req, res) => {
// Generate JWT
const token = jwt.sign({ userId: req.user._id }, process.env.JWT_SECRET);
res.redirect(`/dashboard?token=${token}`);
}
);
// Frontend
<button onClick={() => window.location.href = '/auth/google'}>
Login with Google
</button>
Benefits:
- User ko naya account nahi banana padta
- Password management ki tension nahi
- Trusted providers (Google, Facebook) use karte hain
- Quick signup/login process