J'ai un auth-interceptor.service.ts
pour traiter les demandes
import {Injectable} from '@angular/core';
import {HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';
import {Cookie} from './cookie.service';
import {Router} from '@angular/router';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private router: Router) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Clone the request to add the new header.
const authReq = req.clone({headers: req.headers.set(Cookie.tokenKey, Cookie.getToken())});
// Pass on the cloned request instead of the original request.
return next.handle(authReq).catch(this.handleError);
}
private handleError(err: HttpErrorResponse): Observable<any> {
console.log(err);
if (err.status === 401 || err.status === 403) {
Cookie.deleteUser();
this.router.navigateByUrl(`/login`);
return Observable.of(err.message);
}
// handle your auth error or rethrow
return Observable.throw(err);
}
}
Mais je reçois l'erreur suivante. Rien ne se passe vraiment si vous ne supprimez pas le cookie ou la page de connexion Toute aide ou suggestion serait la bienvenue.
Vous devriez utiliser votre intercepteur et le manipuler comme ceci:
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private router: Router) { }
private handleAuthError(err: HttpErrorResponse): Observable<any> {
//handle your auth error or rethrow
if (err.status === 401 || err.status === 403) {
//navigate /delete cookies or whatever
this.router.navigateByUrl(`/login`);
// if you've caught / handled the error, you don't want to rethrow it unless you also want downstream consumers to have to handle it as well.
return Observable.of(err.message);
}
return Observable.throw(err);
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Clone the request to add the new header.
const authReq = req.clone({headers: req.headers.set(Cookie.tokenKey, Cookie.getToken())});
// catch the error, make specific functions for catching specific errors and you can chain through them with more catch operators
return next.handle(authReq).catch(x=> this.handleAuthError(x)); //here use an arrow function, otherwise you may get "Cannot read property 'navigate' of undefined" on angular 4.4.2/net core 2/webpack 2.70
}
}
pas besoin du wrapper de service http.
pour utiliser le routeur, vous aurez besoin d'un fournisseur d'usine tel que:
providers: [
{
provide: HTTP_INTERCEPTORS,
useFactory: function(router: Router) {
return new AuthInterceptor(router);
},
multi: true,
deps: [Router]
},
.... other providers ...
]
où que vous fournissiez l'intercepteur (probablement app.module). n'utilisez pas une fonction flèche. ils ne sont pas pris en charge dans les fonctions d'usine lorsque vous essayez de générer pour prod.
Temps de travail: https://plnkr.co/edit/UxOEqhEHX1tCDVPDy488?p=preview
De la suggestion de @ bryan60, j'ai apporté peu de modifications à sa solution
Dans app.module.ts:
providers: [
{
provide: HTTP_INTERCEPTORS,
useFactory: function(injector: Injector) {
return new AuthInterceptor(injector);
},
multi: true,
deps: [Injector]
},
.... other providers ...
]
et dans auth-interceptor.service.ts:
import {Injectable, Injector} from '@angular/core';
import {HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';
import {Cookie} from './cookie.service';
import {Router} from '@angular/router';
import {UserService} from './user.service';
import {ToasterService} from '../toaster/toaster.service';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private injector: Injector) {}
private handleError(err: HttpErrorResponse): Observable<any> {
let errorMsg;
if (err.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly.
errorMsg = `An error occurred: ${err.error.message}`;
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
errorMsg = `Backend returned code ${err.status}, body was: ${err.error}`;
}
if (err.status === 404 || err.status === 403) {
this.injector.get(UserService).purgeAuth();
this.injector.get(ToasterService).showError(`Unauthorized`, errorMsg);
this.injector.get(Router).navigateByUrl(`/login`);
}
console.error(errorMsg);
return Observable.throw(errorMsg);
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Clone the request to add the new header.
const authReq = req.clone({headers: req.headers.set(Cookie.tokenKey, Cookie.getToken())});
// Pass on the cloned request instead of the original request.
return next.handle(authReq).catch(err => this.handleError(err));
}
}
Si vous utilisez AOT dans la construction, essayez:
export function authInterceptorFactory(injector: Injector) {
return new AuthInterceptor(injector);
}
providers: [
{
provide: HTTP_INTERCEPTORS,
useFactory: authInterceptorFactory,
multi: true,
deps: [Injector]
},
.... other providers ...
]
la réponse @ bryan60 ci-dessus fonctionne bien, si quelqu'un qui fait face à un problème comme moi reconnaît l'erreur en dessous
return next.handle(authReq).catch(x=> this.handleAuthError(x));
using do () gère l'erreur (si vous faites face à catch ())
import 'rxjs/add/operator/do';
return next.handle(authReq)
.do(
success => {/*todo*/},
err => {this.handleAuthError(authReq)}
);
}
handleAuthError(err: any) {
if(err.status === 401 || err.status === 403) {
this.storageService.clear();
window.location.href = '/home';
}
}
J'espère que c'est aider quelqu'un.