React Js / APIs / refresh token
Refresh token
-
1. Step
Flow
1. Login → receive access + refresh token.
2. Store tokens in localStorage or httpOnly cookie.
3. On 401 (access token expired) → send refresh token to /refresh.
4. Update access token and retry the request.
1. Store Tokens After Login
const handleLogin = async () => { const res = await fetch('/api/login', { method: 'POST', body: JSON.stringify({ email, password }), headers: { 'Content-Type': 'application/json' } }); if (res.ok) { const { accessToken, refreshToken } = await res.json(); localStorage.setItem('accessToken', accessToken); localStorage.setItem('refreshToken', refreshToken); } }; 2. Create a Token Refresh Function
auth.js
export const refreshAccessToken = async () => { const refreshToken = localStorage.getItem('refreshToken'); if (!refreshToken) return null; const res = await fetch('/api/refresh', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ refreshToken }), }); if (!res.ok) { // Refresh token expired or invalid localStorage.removeItem('accessToken'); localStorage.removeItem('refreshToken'); window.location.href = '/login'; return null; } const data = await res.json(); localStorage.setItem('accessToken', data.accessToken); return data.accessToken; }; 3. Create a Fetch Wrapper with Auto-Retry
api.js
import { refreshAccessToken } from './auth'; export const secureFetch = async (url, options = {}) => { let accessToken = localStorage.getItem('accessToken'); const res = await fetch(url, { ...options, headers: { ...(options.headers || {}), 'Authorization': `Bearer ${accessToken}`, }, }); if (res.status === 401) { // Try to refresh token accessToken = await refreshAccessToken(); if (!accessToken) return res; // Retry original request with new token const retryRes = await fetch(url, { ...options, headers: { ...(options.headers || {}), 'Authorization': `Bearer ${accessToken}`, }, }); return retryRes; } return res; }; 4. Use It in Your Components
import { useEffect, useState } from 'react'; import { secureFetch } from './api'; const UserList = () => { const [users, setUsers] = useState([]); useEffect(() => { secureFetch('/api/users') .then(res => res.json()) .then(data => setUsers(data)) .catch(err => console.error(err)); }, []); return ( -
{users.map(user => (
- {user.name} ))}
MANVIA BLOG