nice connexion + ooublications counter
This commit is contained in:
parent
4bf1370543
commit
044751c6d9
@ -149,7 +149,7 @@ from datetime import timedelta
|
||||
|
||||
SIMPLE_JWT = {
|
||||
'ACCESS_TOKEN_LIFETIME': timedelta(days=1),
|
||||
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
|
||||
'REFRESH_TOKEN_LIFETIME': timedelta(days=36500),
|
||||
'ROTATE_REFRESH_TOKENS': True,
|
||||
'BLACKLIST_AFTER_ROTATION': True,
|
||||
'AUTH_HEADER_TYPES': ('Bearer',),
|
||||
|
||||
@ -22,11 +22,12 @@ function expireSession() {
|
||||
}
|
||||
}
|
||||
|
||||
function refreshAccessToken() {
|
||||
export function refreshAccessToken() {
|
||||
if (!refreshPromise) {
|
||||
const refresh = localStorage.getItem('refresh');
|
||||
if (!refresh) return Promise.reject(new Error('Aucun jeton de renouvellement.'));
|
||||
|
||||
refreshPromise = refreshClient.post('/auth/refresh/', { refresh }).then(({ data }) => {
|
||||
// Une déconnexion ou une nouvelle connexion peut avoir eu lieu pendant la requête.
|
||||
if (localStorage.getItem('refresh') !== refresh) {
|
||||
throw new Error('La session a changé.');
|
||||
}
|
||||
@ -43,11 +44,19 @@ function refreshAccessToken() {
|
||||
return refreshPromise;
|
||||
}
|
||||
|
||||
api.interceptors.request.use((config) => {
|
||||
api.interceptors.request.use(async (config) => {
|
||||
const publicRequest = ['/auth/login/', '/users/register/'].includes(config.url);
|
||||
const token = localStorage.getItem('token');
|
||||
config._publicRequest = publicRequest;
|
||||
if (token && !publicRequest) config.headers.Authorization = `Bearer ${token}`;
|
||||
if (publicRequest) {
|
||||
delete config.headers.Authorization;
|
||||
return config;
|
||||
}
|
||||
|
||||
let token = localStorage.getItem('token');
|
||||
if (!token && localStorage.getItem('refresh')) {
|
||||
token = await refreshAccessToken();
|
||||
}
|
||||
if (token) config.headers.Authorization = `Bearer ${token}`;
|
||||
else delete config.headers.Authorization;
|
||||
return config;
|
||||
});
|
||||
@ -65,7 +74,6 @@ api.interceptors.response.use(
|
||||
request._retry = true;
|
||||
const currentToken = localStorage.getItem('token');
|
||||
const sentToken = request.headers.Authorization;
|
||||
// Une autre requête a peut-être déjà renouvelé la session.
|
||||
const access = currentToken && sentToken !== `Bearer ${currentToken}`
|
||||
? currentToken : await refreshAccessToken();
|
||||
request.headers.Authorization = `Bearer ${access}`;
|
||||
|
||||
@ -14,26 +14,32 @@ export const AuthProvider = ({ children }) => {
|
||||
setIsAdmin(false);
|
||||
};
|
||||
window.addEventListener('auth:logout', onLogout);
|
||||
|
||||
const checkAuth = async () => {
|
||||
const token = localStorage.getItem('token');
|
||||
|
||||
if (token) {
|
||||
if (localStorage.getItem('token') || localStorage.getItem('refresh')) {
|
||||
try {
|
||||
// Verify token by fetching user profile
|
||||
const response = await api.get('/users/me/');
|
||||
const userData = response.data;
|
||||
|
||||
if (!cancelled && localStorage.getItem('token')) {
|
||||
const { data: userData } = await api.get('/users/me/');
|
||||
if (!cancelled && (localStorage.getItem('token') || localStorage.getItem('refresh'))) {
|
||||
localStorage.setItem('user', JSON.stringify(userData));
|
||||
setUser(userData);
|
||||
setIsAdmin(userData.is_admin || false);
|
||||
setIsAdmin(Boolean(userData.is_admin));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to verify authentication', error);
|
||||
|
||||
// Une panne réseau ne doit pas effacer la session conservée localement.
|
||||
if (!cancelled && !error.response && localStorage.getItem('refresh')) {
|
||||
try {
|
||||
const cachedUser = JSON.parse(localStorage.getItem('user'));
|
||||
if (cachedUser) {
|
||||
setUser(cachedUser);
|
||||
setIsAdmin(Boolean(cachedUser.is_admin));
|
||||
}
|
||||
} catch {
|
||||
// Le profil en cache est illisible : une prochaine requête pourra le récupérer.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cancelled) setLoading(false);
|
||||
};
|
||||
|
||||
@ -45,52 +51,31 @@ export const AuthProvider = ({ children }) => {
|
||||
}, []);
|
||||
|
||||
const login = async (username, password) => {
|
||||
const response = await api.post('/auth/login/', {
|
||||
username,
|
||||
password,
|
||||
});
|
||||
|
||||
const response = await api.post('/auth/login/', { username, password });
|
||||
const { access, refresh } = response.data;
|
||||
|
||||
localStorage.setItem('token', access);
|
||||
localStorage.setItem('refresh', refresh);
|
||||
|
||||
// Fetch user info after login
|
||||
const userResponse = await api.get('/users/me/');
|
||||
const userData = userResponse.data;
|
||||
|
||||
const { data: userData } = await api.get('/users/me/');
|
||||
localStorage.setItem('user', JSON.stringify(userData));
|
||||
|
||||
setUser(userData);
|
||||
setIsAdmin(userData.is_admin || false);
|
||||
|
||||
setIsAdmin(Boolean(userData.is_admin));
|
||||
return userData;
|
||||
};
|
||||
|
||||
const register = async (data) => {
|
||||
const response = await api.post('/users/register/', data);
|
||||
|
||||
return response.data;
|
||||
};
|
||||
|
||||
const logout = () => {
|
||||
clearSession();
|
||||
|
||||
setUser(null);
|
||||
setIsAdmin(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<AuthContext.Provider
|
||||
value={{
|
||||
user,
|
||||
login,
|
||||
register,
|
||||
logout,
|
||||
loading,
|
||||
isAdmin,
|
||||
}}
|
||||
>
|
||||
<AuthContext.Provider value={{ user, login, register, logout, loading, isAdmin }}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user