Angular5 HttpInterceptor取决于Observable的结果 [英] Angular5 HttpInterceptor depending on the result of an Observable

查看:90
本文介绍了Angular5 HttpInterceptor取决于Observable的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Angular5使用 HttpInterceptor 在所有HTTP请求中注入一个Authorization标头。

I am trying to implement using Angular5 an HttpInterceptor to inject an Authorization header in all HTTP requests.

我依靠第三方库(ADAL,在这里称为 AuthService )公开了 acquireToken()方法来获取

I rely on a third party library (ADAL, here called AuthService) that exposes a acquireToken() method to get the token to be used for Bearer authorization.

问题是 aquireToken()返回一个可观察值,我有

The problem is that aquireToken() returns an observable, and i have to subscribe to get the real string I need.

因此,我想我的代码从不注入标题,因为 next.handle() acquireToken()返回任何值之前执行。

Therefore, my code never injects the header, i suppose because next.handle() is executed before acquireToken() returns any value.

我如何确保下一个

import { Injectable, Injector } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';

import {AuthService} from 'mylibrary';

@Injectable()
export class MyInterceptor implements HttpInterceptor {

    constructor(private auth: AuthService) { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        let headers = req.headers || new HttpHeaders();

        this.auth.acquireToken(req.url)
            .subscribe((token: string) => {
                headers = headers.append('Authorization', 'Bearer ' + token);
            });

        return next.handle(req.clone({ headers: headers }));
    }
}


推荐答案

此代码即可完成工作,诀窍是使用 mergeMap

This code will do the job, the trick is using mergeMap

import { Injectable, Injector } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { AdalService } from './adal.service';
import 'rxjs/add/operator/mergeMap';

@Injectable()
export class AdalInterceptor implements HttpInterceptor {

    constructor(private adal: AdalService) { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        // if the endpoint is not registered then pass
        // the request as it is to the next handler
        const resource = this.adal.GetResourceForEndpoint(req.url);
        if (!resource) {
            return next.handle(req.clone());
        }

        // if the endpoint is registered then acquire and inject token
        let headers = req.headers || new HttpHeaders();
        return this.adal.acquireToken(resource)
            .mergeMap((token: string) => {
                // if the user is not authenticated then drop the request
                if (!this.adal.userInfo.authenticated) {
                    throw new Error('Cannot send request to registered endpoint if the user is not authenticated.');
                }

                // inject the header
                headers = headers.append('Authorization', 'Bearer ' + token);
                return next.handle(req.clone({ headers: headers }));
            }
        );
    }
}

这篇关于Angular5 HttpInterceptor取决于Observable的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆