我正在使用Angular 7的angular-oauth2-oidc。我相信它会使用导入功能导入一个拦截器
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);
}
在拦截网址之前,导入的拦截器显然无法正常工作。
如何确保导入的拦截器在链中自己的拦截器之后?
作为临时解决方案,我在allowedUrl中添加了“ /”,但我不喜欢这种解决方法。
答案 0 :(得分:2)
好角度按您提供拦截器的顺序应用拦截器。来自doc:
Angular按提供拦截器的顺序应用拦截器。如果您提供拦截器A,然后是B,然后是C,则请求将在A-> B-> C中流动,而响应将在C-> B-> A中流出。
您以后不能更改顺序或删除拦截器。如果你需要 要动态启用和禁用拦截器,您必须构建 这种能力进入拦截器本身。
所以我想您需要告诉您的模块不要提供拦截器并自行声明。
快速浏览lib documentation,除了使用sendAccessToken来伪造并实现自定义拦截器来完成这项工作外,您别无选择。
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));
}
}