OAuth2暗黙フローを使用するAngular 5アプリケーションで作業しています。
私のサービスの一例に従って、HTTP呼び出しを実行するサービスがあります。
@Injectable()
export class MyService {
constructor(public http: HttpClient) { }
public getAll(): Observable<Persona[]> {
return this.http.get<Persona[]>("http://mywebservice/persone");
}
}
承認にインターセプターを使用し、カスタム属性を追加しています。私の認証インターセプターに従って:
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from "rxjs";
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor() {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let accessToken = sessionStorage.getItem("access_token");
if(accessToken)
{
request = request.clone({
setHeaders: {
Authorization: `Bearer ${accessToken}`
}
});
}
return next.handle(request);
}
}
そして、私が自分のサービスをどのように消費するかに従ってください:
public myMethod() {
this.myService.getAll().subscribe(
result => {
console.log(result);
}, error => {
// I don't want add redirection there...
console.error(error);
});
}
ここで必要なのは、HTTP呼び出しが401の結果を受け取ると、アプリケーションがユーザーをログインページにリダイレクトすることです。
コードを複製せずにこの結果を取得するにはどうすればよいですか?
大いに感謝する
次のようにインターセプターを変更して問題を解決しました:
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor() {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let accessToken = sessionStorage.getItem("access_token");
if(accessToken)
{
request = request.clone({
setHeaders: {
Authorization: `Bearer ${accessToken}`
}
});
}
return next.handle(request).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
}
}, (err: any) => {
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
this.router.navigate(['login']);
}
}
});
}
}
そこで解決策を見つけました: https://medium.com/@ryanchenkie_40935/angular-authentication-using-the-http-client-and-http-interceptors-2f9d1540eb8
新しいリーダーをサポートするためだけに、angular 7ではdo()またはcatch()の代わりにpipe()を使用する必要があることに注意してください。
return next.handle(request).pipe(catchError(err => {
if (err.status === 401) {
MyComponent.logout();
}
const error = err.error.message || err.statusText;
return throwError(error);
}));
エラー処理を共通のリクエストハンドラにアタッチします。
return next.handle(request).catch(err => {
if (err.status === 401) {
// Redirect here
}
}
ルーターをインターセプターに直接インポートできますが、適切な方法は、ルーターをインポートしてリダイレクトを行う認証サービスなどを作成することです