Le maintien des sessions utilisateur sans connexions constantes est la clé d'une expérience Web fluide. Dans ce blog, je vais vous montrer comment implémenter un workflow d'actualisation de jetons dans Angular, en gérant les erreurs 401 et en gérant efficacement les demandes simultanées.
Dans les systèmes d'authentification, les jetons d'accès ont une courte durée de vie pour minimiser les risques de sécurité. Lorsqu'un jeton d'accès expire, le jeton d'actualisation permet à l'application de demander un nouveau jeton d'accès au serveur sans nécessiter que l'utilisateur se reconnecte.
Nous allons implémenter un mécanisme de jeton d'actualisation à l'aide du HttpInterceptor d'Angular. L'objectif est d'intercepter les requêtes non autorisées (erreurs 401) et d'actualiser le token avant de réessayer la requête d'origine.
Demande d'interception :
Un intercepteur détecte une réponse 401 non autorisée.
Actualisation du jeton :
Si le jeton est expiré, rafraîchirToken récupère un nouveau jeton.
Demande de nouvelle tentative :
La demande d'origine est réessayée avec le nouveau jeton.
Gestion des files d'attente :
Les demandes en attente sont traitées une fois le jeton actualisé.
handleUnauthorized( req: HttpRequest<any>, next: HttpHandlerFn ): Observable<any> { if (!this.isRefreshingToken) { this.isRefreshingToken = true; // Notify all waiting requests that the token is being refreshed this.tokenSubject.next(null); return this.refreshToken().pipe( switchMap((newToken: string) => { if (newToken) { this.tokenSubject.next(newToken); // Retry the original request with the new token return next(this.addToken(req, newToken)); } // If token refresh fails, log out the user this.logout(); return throwError(() => 'Token expired'); }), catchError((error) => { this.logout(); // Log out on error return throwError(() => error); }), finalize(() => { this.isRefreshingToken = false; // Reset the flag }), ); } else { // Queue requests while a token is being refreshed return this.tokenSubject.pipe( filter((token) => token != null), take(1), switchMap((token) => next(this.addToken(req, token))), ); } }
La fonction handleUnauthorized est conçue pour gérer les scénarios dans lesquels une requête HTTP reçoit un statut 401 non autorisé, indiquant que le jeton d'accès a expiré ou n'est pas valide. Cette fonction garantit que l'application peut actualiser le jeton et réessayer la demande ayant échoué de manière transparente.
handleUnauthorized( req: HttpRequest<any>, next: HttpHandlerFn ): Observable<any> { if (!this.isRefreshingToken) { this.isRefreshingToken = true; // Notify all waiting requests that the token is being refreshed this.tokenSubject.next(null); return this.refreshToken().pipe( switchMap((newToken: string) => { if (newToken) { this.tokenSubject.next(newToken); // Retry the original request with the new token return next(this.addToken(req, newToken)); } // If token refresh fails, log out the user this.logout(); return throwError(() => 'Token expired'); }), catchError((error) => { this.logout(); // Log out on error return throwError(() => error); }), finalize(() => { this.isRefreshingToken = false; // Reset the flag }), ); } else { // Queue requests while a token is being refreshed return this.tokenSubject.pipe( filter((token) => token != null), take(1), switchMap((token) => next(this.addToken(req, token))), ); } }
if (!this.isRefreshingToken) { this.isRefreshingToken = true; this.tokenSubject.next(null);
return this.refreshToken(url).pipe( switchMap((newToken: string) => { if (newToken) { this.tokenSubject.next(newToken); return next(this.addToken(req, newToken)); } this.logout(); return throwError(() => 'Token expired'); }),
return this.tokenSubject.pipe( filter((token) => token != null), // Wait for a non-null token take(1), // Only take the first emitted token switchMap((token) => next(this.addToken(req, token))), );
catchError((error) => { this.logout(); return throwError(() => error); }),
Ajout du jeton aux requêtes
La méthode addToken ajoute le nouveau jeton aux en-têtes de la requête sortante.
finalize(() => { this.isRefreshingToken = false; }),
Un HttpInterceptor est l'endroit idéal pour implémenter ce workflow. Il vous permet d'intercepter toutes les requêtes HTTP et de gérer la gestion des jetons globalement sans modifier les appels de service individuels.
addToken(request: HttpRequest<any>, token: string): HttpRequest<any> { return request.clone({ setHeaders: { 'X-Token': token, }, }); }
En résumé, un solide workflow d'actualisation des jetons garantit une expérience utilisateur transparente et une gestion sécurisée des sessions dans les applications Angular. En traitant efficacement les erreurs 401 et en gérant les demandes simultanées, vous pouvez maintenir la fiabilité et satisfaire vos utilisateurs. Merci d'avoir lu, n'hésitez pas à partager vos réflexions ou vos questions ci-dessous !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!