Angular 2
HTTP Interceptor
Suche…
Bemerkungen
Was wir mit der HttpServiceLayer-Klasse tun, ist, die Http-Klasse von angle zu erweitern und unsere eigene Logik hinzuzufügen.
Wir fügen dann diese Klasse in die Bootstrap-Klasse der Anwendung ein und teilen dem Angreifer mit, dass wir die Http-Klasse importieren würden, in der Rückseite, um den HttpServiceLayer einzufügen.
Überall im Code können wir einfach importieren
import { Http } from '@angular/http';
Unsere Klasse wird jedoch für jeden Anruf verwendet.
Einfache Klasse Erweiterung der Http-Klasse von Winkeln
import { Http, Request, RequestOptionsArgs, Response, RequestOptions, ConnectionBackend, Headers } from '@angular/http';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/empty';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';
import { ApplicationConfiguration } from '../application-configuration/application-configuration';
/**
* This class extends the Http class from angular and adds automaticaly the server URL(if in development mode) and 2 headers by default:
* Headers added: 'Content-Type' and 'X-AUTH-TOKEN'.
* 'Content-Type' can be set in any othe service, and if set, it will NOT be overwritten in this class any more.
*/
export class HttpServiceLayer extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private _router: Router, private appConfig: ApplicationConfiguration) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
this.getRequestOptionArgs(options);
return this.intercept(super.request(this.appConfig.getServerAdress() + url, options));
}
/**
* This method checks if there are any headers added and if not created the headers map and ads 'Content-Type' and 'X-AUTH-TOKEN'
* 'Content-Type' is not overwritten if it is allready available in the headers map
*/
getRequestOptionArgs(options?: RequestOptionsArgs): RequestOptionsArgs {
if (options == null) {
options = new RequestOptions();
}
if (options.headers == null) {
options.headers = new Headers();
}
if (!options.headers.get('Content-Type')) {
options.headers.append('Content-Type', 'application/json');
}
if (this.appConfig.getAuthToken() != null) {
options.headers.append('X-AUTH-TOKEN', this.appConfig.getAuthToken());
}
return options;
}
/**
* This method as the name sugests intercepts the request and checks if there are any errors.
* If an error is present it will be checked what error there is and if it is a general one then it will be handled here, otherwise, will be
* thrown up in the service layers
*/
intercept(observable: Observable<Response>): Observable<Response> {
// return observable;
return observable.catch((err, source) => {
if (err.status == 401) {
this._router.navigate(['/login']);
//return observable;
return Observable.empty();
} else {
//return observable;
return Observable.throw(err);
}
});
}
}
Verwendung unserer Klasse anstelle von Angulars Http
Nach der Erweiterung der Http-Klasse müssen wir winkelt anweisen, diese Klasse anstelle der Http-Klasse zu verwenden.
Dazu müssen wir in unserem Hauptmodul (oder je nach Bedarf nur ein bestimmtes Modul) in den Abschnitt Provider schreiben:
export function httpServiceFactory(xhrBackend: XHRBackend, requestOptions: RequestOptions, router: Router, appConfig: ApplicationConfiguration) {
return new HttpServiceLayer(xhrBackend, requestOptions, router, appConfig);
}
import { HttpModule, Http, Request, RequestOptionsArgs, Response, XHRBackend, RequestOptions, ConnectionBackend, Headers } from '@angular/http';
import { Router } from '@angular/router';
@NgModule({
declarations: [ ... ],
imports: [ ... ],
exports: [ ... ],
providers: [
ApplicationConfiguration,
{
provide: Http,
useFactory: httpServiceFactory,
deps: [XHRBackend, RequestOptions, Router, ApplicationConfiguration]
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
Hinweis: ApplicationConfiguration ist nur ein Dienst, den ich für die Dauer der Anwendung verwende
Simple HttpClient AuthToken Interceptor (Angular 4.3+)
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { UserService } from '../services/user.service';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class AuthHeaderInterceptor implements HttpInterceptor {
constructor(private userService: UserService) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.userService.isAuthenticated()) {
req = req.clone({
setHeaders: {
Authorization: `Bearer ${this.userService.token}`
}
});
}
return next.handle(req);
}
}
Bereitstellen von Interceptor (some-module.module.ts)
{provide: HTTP_INTERCEPTORS, useClass: AuthHeaderInterceptor, multi: true},