Opis
Najlepszym rozwiązaniem, jakie znalazłem, jest zastąpienie XHRBackendtakiego stanu odpowiedzi HTTP 401i 403prowadzi do określonej akcji.
Jeśli obsługujesz uwierzytelnianie poza aplikacją Angular, możesz wymusić odświeżenie bieżącej strony, tak aby wyzwolony został mechanizm zewnętrzny. Wyszczególniam to rozwiązanie w realizacji poniżej.
Możesz również przekazać do składnika w aplikacji, tak aby aplikacja Angular nie została ponownie załadowana.
Realizacja
Kątowy> 2.3.0
Dzięki @mrgoos, tutaj jest uproszczone rozwiązanie dla angular 2.3.0+ z powodu poprawki błędu w angular 2.3.0 (patrz wydanie https://github.com/angular/angular/issues/11606 ) rozszerzające bezpośrednio Httpmoduł.
import { Injectable } from '@angular/core';
import { Request, XHRBackend, RequestOptions, Response, Http, RequestOptionsArgs, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
@Injectable()
export class AuthenticatedHttpService extends Http {
constructor(backend: XHRBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
return super.request(url, options).catch((error: Response) => {
if ((error.status === 401 || error.status === 403) && (window.location.href.match(/\?/g) || []).length < 2) {
console.log('The authentication session expires or the user is not authorised. Force refresh of the current page.');
window.location.href = window.location.href + '?' + new Date().getMilliseconds();
}
return Observable.throw(error);
});
}
}
Plik modułu zawiera teraz tylko następującego dostawcę.
providers: [
{ provide: Http, useClass: AuthenticatedHttpService }
]
Innym rozwiązaniem przy użyciu routera i zewnętrzną usługę uwierzytelniania jest szczegółowo w poniższej GIST przez @mrgoos.
Angular przed 2.3.0
Następująca implementacja działa dla Angular 2.2.x FINALi RxJS 5.0.0-beta.12.
Przekierowuje do bieżącej strony (plus parametr umożliwiający uzyskanie unikalnego adresu URL i uniknięcie buforowania), jeśli zostanie zwrócony kod HTTP 401 lub 403.
import { Request, XHRBackend, BrowserXhr, ResponseOptions, XSRFStrategy, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
export class AuthenticationConnectionBackend extends XHRBackend {
constructor(_browserXhr: BrowserXhr, _baseResponseOptions: ResponseOptions, _xsrfStrategy: XSRFStrategy) {
super(_browserXhr, _baseResponseOptions, _xsrfStrategy);
}
createConnection(request: Request) {
let xhrConnection = super.createConnection(request);
xhrConnection.response = xhrConnection.response.catch((error: Response) => {
if ((error.status === 401 || error.status === 403) && (window.location.href.match(/\?/g) || []).length < 2) {
console.log('The authentication session expires or the user is not authorised. Force refresh of the current page.');
window.location.href = window.location.href + '?' + new Date().getMilliseconds();
}
return Observable.throw(error);
});
return xhrConnection;
}
}
z następującym plikiem modułu.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpModule, XHRBackend } from '@angular/http';
import { AppComponent } from './app.component';
import { AuthenticationConnectionBackend } from './authenticated-connection.backend';
@NgModule({
bootstrap: [AppComponent],
declarations: [
AppComponent,
],
entryComponents: [AppComponent],
imports: [
BrowserModule,
CommonModule,
HttpModule,
],
providers: [
{ provide: XHRBackend, useClass: AuthenticationConnectionBackend },
],
})
export class AppModule {
}