如何正确链接导入的拦截器

时间:2019-03-12 10:37:53

标签: angular

我正在使用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中添加了“ /”,但我不喜欢这种解决方法。

1 个答案:

答案 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));

    }

}