Composable pour la gestion de l'authentification, des tokens JWT, de l'état administrateur et des identifiants de requête. Il gère la persistance via les cookies et le state Nuxt.
Le composable useAuth centralise toute la logique d'authentification de l'application. Il gère les tokens d'accès et de rafraîchissement, l'état administrateur, et les identifiants de requête avec persistance automatique.
flowchart LR
A[useAuth] --> B[Tokens JWT]
A --> C[État Admin]
A --> D[Request ID]
B --> E[Cookies]
B --> F[useState]
C --> F
D --> E
D --> F
getToken(): string | nullRécupère le token JWT d'authentification. Vérifie d'abord useState, puis les cookies.
const { getToken } = useAuth();
const token = getToken();
if (token) {
// Utiliser le token pour les requêtes API
}
setToken(newToken: string, newRefreshToken?: string): voidDéfinit le token d'accès et optionnellement le token de rafraîchissement. Persiste dans les cookies et le state.
const { setToken } = useAuth();
setToken('jwt-token', 'refresh-token');
Paramètres :
newToken : Token JWT d'accèsnewRefreshToken : Token de rafraîchissement (optionnel)Configuration des cookies :
auth_token : MaxAge 24 heures, secure, sameSite strictrefresh_token : MaxAge 7 jours, secure, sameSite strictremoveToken(): voidSupprime les tokens d'authentification (accès et rafraîchissement) du state et des cookies.
const { removeToken } = useAuth();
removeToken(); // Déconnexion
isAuthenticated(): booleanVérifie si l'utilisateur est authentifié (token présent).
const { isAuthenticated } = useAuth();
if (isAuthenticated()) {
// Utilisateur connecté
}
getRefreshToken(): string | nullRécupère le token de rafraîchissement.
const { getRefreshToken } = useAuth();
const refreshToken = getRefreshToken();
refreshAccessToken(): Promise<boolean>Renouvelle le token d'accès en utilisant le token de rafraîchissement.
const { refreshAccessToken } = useAuth();
const success = await refreshAccessToken();
if (success) {
// Token renouvelé avec succès
}
Retour : true si le renouvellement a réussi, false sinon.
Comportement :
/api/auth/refresh avec le refresh tokengetIsAdmin(): booleanRécupère l'état administrateur.
const { getIsAdmin } = useAuth();
if (getIsAdmin()) {
// Mode administrateur actif
}
setIsAdmin(newIsAdmin: boolean): voidDéfinit l'état administrateur.
const { setIsAdmin } = useAuth();
setIsAdmin(true);
getRequestId(): string | nullRécupère l'identifiant de requête actuel.
const { getRequestId } = useAuth();
const requestId = getRequestId();
setRequestId(id: string): voidDéfinit l'identifiant de requête. Persiste dans un cookie avec maxAge de 24 heures.
const { setRequestId } = useAuth();
setRequestId('request-123');
removeRequestId(): voidSupprime l'identifiant de requête.
const { removeRequestId } = useAuth();
removeRequestId();
initializeFromCookies(): voidInitialise le state depuis les cookies au montage de l'application.
const { initializeFromCookies } = useAuth();
onMounted(() => {
initializeFromCookies();
});
Note : Cette fonction est généralement appelée automatiquement dans un plugin ou middleware.
<script setup lang="ts">
const { getToken, isAuthenticated, setToken, removeToken } = useAuth();
// Vérifier l'authentification
if (isAuthenticated()) {
const token = getToken();
// Utiliser le token
}
// Connexion
async function login(email: string, password: string) {
const response = await $fetch('/api/auth', {
method: 'POST',
body: { email, password },
});
setToken(response.token, response.refresh_token);
}
// Déconnexion
function logout() {
removeToken();
navigateTo('/');
}
</script>
// middleware/auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
const { isAuthenticated } = useAuth();
if (!isAuthenticated()) {
return navigateTo('/login');
}
});
const { getToken } = useAuth();
const token = getToken();
const { data } = await $fetch('/api/protected', {
headers: {
Authorization: `Bearer ${token}`,
},
});
const { refreshAccessToken, isAuthenticated } = useAuth();
// Dans un plugin ou middleware
if (isAuthenticated()) {
const refreshed = await refreshAccessToken();
if (!refreshed) {
// Token invalide, rediriger vers login
navigateTo('/login');
}
}
<script setup lang="ts">
const { getIsAdmin, setIsAdmin } = useAuth();
const isAdmin = computed(() => getIsAdmin());
function toggleAdminMode() {
setIsAdmin(!isAdmin.value);
}
</script>
<template>
<div v-if="isAdmin">
<UAlert
icon="i-heroicons-shield-check"
color="info"
title="Mode administrateur"
/>
</div>
</template>
Les données sont persistées dans des cookies avec les configurations suivantes :
| Cookie | MaxAge | Secure | SameSite |
|---|---|---|---|
auth_token | 24h | Oui | Strict |
refresh_token | 7j | Oui | Strict |
request_id | 24h | Oui | Strict |
Les données sont également stockées dans le state Nuxt via useState pour un accès rapide côté client :
auth_token : Token JWT d'accèsrefresh_token : Token de rafraîchissementrequest_id : Identifiant de requêteadmin : État administrateur (boolean)secure: true)sameSite: 'strict' pour prévenir les attaques CSRFinitializeFromCookies() est appelé/api/auth/refresh est accessible<template>
<div>
<div v-if="isAuthenticated()">
<p>Connecté en tant que : {{ user.email }}</p>
<UButton @click="handleLogout">Déconnexion</UButton>
</div>
<div v-else>
<UForm @submit="handleLogin">
<UFormGroup label="Email" name="email">
<UInput v-model="loginForm.email" type="email" />
</UFormGroup>
<UFormGroup label="Mot de passe" name="password">
<UInput v-model="loginForm.password" type="password" />
</UFormGroup>
<UButton type="submit" :loading="loading">
Connexion
</UButton>
</UForm>
</div>
</div>
</template>
<script setup lang="ts">
const {
getToken,
setToken,
removeToken,
isAuthenticated,
refreshAccessToken
} = useAuth();
const loginForm = reactive({
email: '',
password: '',
});
const loading = ref(false);
const user = ref<any>(null);
// Vérifier et renouveler le token au montage
onMounted(async () => {
if (isAuthenticated()) {
const refreshed = await refreshAccessToken();
if (refreshed) {
await loadUser();
} else {
removeToken();
}
}
});
async function handleLogin() {
loading.value = true;
try {
const response = await $fetch('/api/auth', {
method: 'POST',
body: loginForm,
});
setToken(response.token, response.refresh_token);
await loadUser();
} catch (error) {
console.error('Erreur de connexion:', error);
} finally {
loading.value = false;
}
}
async function loadUser() {
const token = getToken();
if (!token) return;
try {
const { data } = await $fetch('/api/user', {
headers: {
Authorization: `Bearer ${token}`,
},
});
user.value = data;
} catch (error) {
console.error('Erreur de chargement utilisateur:', error);
}
}
function handleLogout() {
removeToken();
user.value = null;
navigateTo('/');
}
</script>