Опис
Найкраще рішення, яке я знайшов, - це перевизначення XHRBackendтакого, що статус відповіді HTTP 401і 403призводить до певної дії.
Якщо ви виконуєте автентифікацію поза вашим додатком Angular, ви можете примусити оновити поточну сторінку так, щоб спрацьовував ваш зовнішній механізм. Я детально описую це рішення у реалізації нижче.
Ви також можете переслати на компонент у вашій програмі таким чином, щоб програма Angular не перезавантажувалася.
Впровадження
Кутовий> 2.3.0
Завдяки @mrgoos, ось спрощене рішення для angular 2.3.0+ завдяки виправленню помилок у angular 2.3.0 (див. Випуск https://github.com/angular/angular/issues/11606 ), що безпосередньо розширює Httpмодуль.
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);
});
}
}
Файл модуля тепер містить лише наступного постачальника.
providers: [
{ provide: Http, useClass: AuthenticatedHttpService }
]
Інше рішення з допомогою маршрутизатора і зовнішньої служби аутентифікації докладно описаний в наступній суті по @mrgoos.
Кутовий пре-2.3.0
Наступна реалізація працює для Angular 2.2.x FINALта RxJS 5.0.0-beta.12.
Він переспрямовує на поточну сторінку (плюс параметр для отримання унікальної URL-адреси та уникнення кешування), якщо повертається код HTTP 401 або 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;
}
}
з наступним файлом модуля.
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 {
}