我正在使用 angular-oauth2-oidc,Angular 7。我相信它会导入一个带有导入的拦截器
OAuthModule.forRoot({
resourceServer: {
allowedUrls: [environment.backendUrl],
sendAccessToken: true
}
})
此外,我还有一个完成 url 的拦截器,它允许我在服务的 httpClient 调用中仅使用相对路径。例如
this.httpClient.get('/resource/' + id)
然后截取到后端的完整url
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (!req.url.startsWith('/') || req.url.startsWith('/assets')) {
return next.handle(req);
}
const modifiedUrl: string = environment.backendUrl + req.url;
const modifiedRequest = req.clone({ url: modifiedUrl });
return next.handle(modifiedRequest);
}
在url被拦截之前导入的Interceptor显然是不行的。
我如何确保导入的拦截器在链中自己的拦截器之后?
作为临时解决方案,我向 allowedUrls 添加了“/”,但我不喜欢这种解决方法。
最佳答案
Angular 会按照您提供的顺序应用拦截器。来自doc :
Angular applies interceptors in the order that you provide them. If you provide interceptors A, then B, then C, requests will flow in A->B->C and responses will flow out C->B->A.
You cannot change the order or remove interceptors later. If you need to enable and disable an interceptor dynamically, you'll have to build that capability into the interceptor itself.
所以我猜你需要告诉你的模块不要提供拦截器并自己声明它。
快速浏览 lib documentation您别无选择,只能将 sendAccessToken 设置为 false 并实现自定义拦截器来完成这项工作。
import { Injectable, Inject, Optional } from '@angular/core';
import { OAuthService, OAuthStorage } from 'angular-oauth2-oidc';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse, HttpErrorResponse } from '@angular/common/http';
import {Observable} from 'rxjs/Observable';
import { OAuthResourceServerErrorHandler } from "./resource-server-error-handler";
import { OAuthModuleConfig } from "../oauth-module.config";
import 'rxjs/add/operator/catch';
@Injectable()
export class DefaultOAuthInterceptor implements HttpInterceptor {
constructor(
private authStorage: OAuthStorage,
private errorHandler: OAuthResourceServerErrorHandler,
@Optional() private moduleConfig: OAuthModuleConfig
) {
}
private checkUrl(url: string): boolean {
let found = this.moduleConfig.resourceServer.allowedUrls.find(u => url.startsWith(u));
return !!found;
}
public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let url = req.url.toLowerCase();
if (!this.moduleConfig) return next.handle(req);
if (!this.moduleConfig.resourceServer) return next.handle(req);
if (!this.moduleConfig.resourceServer.allowedUrls) return next.handle(req);
if (!this.checkUrl(url)) return next.handle(req);
let sendAccessToken = this.moduleConfig.resourceServer.sendAccessToken;
if (sendAccessToken) {
let token = this.authStorage.getItem('access_token');
let header = 'Bearer ' + token;
let headers = req.headers
.set('Authorization', header);
req = req.clone({ headers });
}
return next.handle(req).catch(err => this.errorHandler.handleError(err));
}
}
关于angular - 如何正确链接导入的拦截器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55119437/