JWT authentication stores tokens securely and handles refresh logic.
Code:
1// Auth context2const AuthContext = createContext(null);34export function AuthProvider({ children }) {5 const [user, setUser] = useState(null);6 const [loading, setLoading] = useState(true);78 useEffect(() => {9 const token = getCookie("token");10 if (token) {11 fetchUser(token).then(setUser).finally(() => setLoading(false));12 } else {13 setLoading(false);14 }15 }, []);1617 const login = async (email, password) => {18 const { token } = await api.login(email, password);19 setCookie("token", token, { httpOnly: true, secure: true });20 const user = await fetchUser(token);21 setUser(user);22 };2324 const logout = async () => {25 await api.logout();26 deleteCookie("token");27 setUser(null);28 };2930 return (31 <AuthContext.Provider value={{ user, login, logout, loading }}>32 {children}33 </AuthContext.Provider>34 );35}
Token refresh:
1// api.ts2let isRefreshing = false;3let failedQueue: Array<{resolve: Function, reject: Function}> = [];45const processQueue = (error, token = null) => {6 failedQueue.forEach(prom => {7 if (error) prom.reject(error);8 else prom.resolve(token);9 });10 failedQueue = [];11};1213api.interceptors.response.use(14 response => response,15 async error => {16 const originalRequest = error.config;1718 if (error.response?.status === 401 && !originalRequest._retry) {19 if (isRefreshing) {20 return new Promise((resolve, reject) => {21 failedQueue.push({ resolve, reject });22 }).then(token => {23 originalRequest.headers.Authorization = `Bearer ${token}`;24 return api(originalRequest);25 });26 }2728 originalRequest._retry = true;29 isRefreshing = true;3031 try {32 const { token } = await refreshAuthToken();33 processQueue(null, token);34 originalRequest.headers.Authorization = `Bearer ${token}`;35 return api(originalRequest);36 } catch (err) {37 processQueue(err);38 logout();39 return Promise.reject(err);40 } finally {41 isRefreshing = false;42 }43 }44 return Promise.reject(error);45 }46);
Security best practices: