Harden web session handling and production config
This commit is contained in:
@@ -6,7 +6,7 @@ export const register = (data) => client.post('/auth/register', data, {
|
||||
},
|
||||
});
|
||||
export const login = (data) => client.post('/auth/login', data);
|
||||
export const logout = (refreshToken) => client.post('/auth/logout', { refreshToken });
|
||||
export const logout = () => client.post('/auth/logout', {});
|
||||
export const getMe = () => client.get('/auth/me');
|
||||
export const verifyEmail = (token) => client.get(`/auth/verify/${token}`);
|
||||
export const changePassword = (data) => client.patch('/auth/change-password', data);
|
||||
|
||||
@@ -5,6 +5,7 @@ const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:4000';
|
||||
const client = axios.create({
|
||||
baseURL: API_URL,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
withCredentials: true,
|
||||
});
|
||||
|
||||
client.interceptors.request.use((config) => {
|
||||
@@ -19,18 +20,16 @@ client.interceptors.response.use(
|
||||
const original = error.config;
|
||||
if (error.response?.status === 401 && !original._retry) {
|
||||
original._retry = true;
|
||||
const refreshToken = localStorage.getItem('refreshToken');
|
||||
if (refreshToken) {
|
||||
const hadAccessToken = Boolean(localStorage.getItem('accessToken'));
|
||||
if (hadAccessToken) {
|
||||
try {
|
||||
const { data } = await axios.post(`${API_URL}/auth/refresh`, { refreshToken });
|
||||
const { accessToken, refreshToken: newRefresh } = data.data;
|
||||
const { data } = await axios.post(`${API_URL}/auth/refresh`, {}, { withCredentials: true });
|
||||
const { accessToken } = data.data;
|
||||
localStorage.setItem('accessToken', accessToken);
|
||||
localStorage.setItem('refreshToken', newRefresh);
|
||||
original.headers.Authorization = `Bearer ${accessToken}`;
|
||||
return client(original);
|
||||
} catch {
|
||||
localStorage.removeItem('accessToken');
|
||||
localStorage.removeItem('refreshToken');
|
||||
window.location.href = '/login';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ export function AuthProvider({ children }) {
|
||||
.then(({ data }) => setUser(data.data.user))
|
||||
.catch(() => {
|
||||
localStorage.removeItem('accessToken');
|
||||
localStorage.removeItem('refreshToken');
|
||||
})
|
||||
.finally(() => setLoading(false));
|
||||
} else {
|
||||
@@ -25,18 +24,15 @@ export function AuthProvider({ children }) {
|
||||
|
||||
const login = useCallback(async (email, password) => {
|
||||
const { data } = await apiLogin({ email, password });
|
||||
const { accessToken, refreshToken, user: userData } = data.data;
|
||||
const { accessToken, user: userData } = data.data;
|
||||
localStorage.setItem('accessToken', accessToken);
|
||||
localStorage.setItem('refreshToken', refreshToken);
|
||||
setUser(userData);
|
||||
return userData;
|
||||
}, []);
|
||||
|
||||
const logout = useCallback(async () => {
|
||||
const refreshToken = localStorage.getItem('refreshToken');
|
||||
try { await apiLogout(refreshToken); } catch { /* ignore */ }
|
||||
try { await apiLogout(); } catch { /* ignore */ }
|
||||
localStorage.removeItem('accessToken');
|
||||
localStorage.removeItem('refreshToken');
|
||||
setUser(null);
|
||||
}, []);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user