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

标签 angular

我正在使用 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/

相关文章:

javascript - 为什么 getBoundingClientRect 在调整大小后不返回新值

javascript - angular 4 如何在外部js中调用一个函数

javascript - 更新到 Angular 8 后找不到模块 @angular/common/http/src/params

angular - 设置 angular cli production build tfs

angular - 无法使用 moment 调用类型缺少调用签名的表达式

html - Angular 不渲染从组件中提取的 HTML?

java - Angular 8删除方法不调用Spring Boot删除方法

angular - 从内部 div 检测滚动事件

angular - 导航栏不使用 ng-bootstrap 和 Angular 4 在浏览器中呈现

angular - NSWAG Angular 客户端生成 IFormFile 问题