Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 652|回复: 0

Angular4---认证---使用HttpClient拦截器,解决循环依赖引用的问题

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-14 15:52:53 | 显示全部楼层 |阅读模式

      在angular4 项目中,每次请求服务端需要添加头部信息AccessToken作为认证的凭据。但如果在每次调用服务端就要写代码添加一个头部信息,会变得很麻烦。可以使用angular4的HttpClient来拦截每个请求,然后在头部添加上信息。

      直接上代码实践

      一、创建拦截器Service,实现HttpInterceptor的intercept方法

    import { Injectable, Injector} from '@angular/core';
    import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http';
    import {Observable} from 'rxjs/Observable';
    import 'rxjs/add/operator/do';
    import {AuthenticationService} from './auth/authentication.service'; // 用于获得AccessToken的服务类
    import {environment} from '../../environments/environment';
    
    /**
     * HTTP拦截器,设置头部信息
     */
    @Injectable()
    export class BaseHttpInterceptorService implements HttpInterceptor {
    
      authService: AuthenticationService;
      skipAuth: [string];
      constructor(private inject: Injector) {
      // 用户登录或认证请求则不需要添加头部AccessToken信息
        this.skipAuth = [
          `${environment.serverUrl}/api/v1/User/login`,
        ];
      }
      /**
       * 拦截器拦截请求
       * @param {HttpRequest<any>} req
       * @param {HttpHandler} next
       * @returns {Observable<HttpEvent<any>>}
       */
      intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        this.authService = this.inject.get(AuthenticationService);// 注意此句 const req_started = Date.now();
        let authReq;
        /**
         * 如果是跳过认证的链接,则不添加头部信息
         */
        if (this.isSkipAuth(req.url)) {
          authReq = req.clone();
        }else {
          const access_token = `Bearer ${this.authService.getAccessToken('563151811@qq.com')}`;
          authReq = req.clone({
            setHeaders: {
              Authorization: access_token
            }
          });
        }
        return next.handle(authReq).do(event => {
          if (event instanceof HttpResponse) {
            const elapsed = Date.now() - req_started;
            console.log(`Request for ${req.urlWithParams} took ${elapsed} ms`);
          }
        });
      }
      /*
       *是否跳过添加头部认证
      */
      isSkipAuth(url: string) {
        let isMatch = false;
        this.skipAuth.forEach((reg_url: string) => {
          if ( !isMatch) {
            if (url.search(reg_url) >= 0) {
              isMatch = true;
            }
          }
        });
        return isMatch;
      }
    }

      二、注册拦截器,在APPModule中,添加如下代码

    {
          provide: HTTP_INTERCEPTORS,
          useClass: BaseHttpInterceptorService,// 上边定义的拦截器名字
          multi: true
        },

      三、每个请求服务端数据的Service依赖HttpClient,而不是http。

      那么一个基础的拦截器已经完成了,但是,你会发现调用认证服务Service的时候,会报错:Cyclic dependency error with HttpInterceptor ,如果添加了第一步代码中注意点那段代码后,又会发现OK了。

      这是依赖注入循环嵌套:A依赖B,B中又引用A。

      官方文档中采用forwardRef,但是发现没用。在Stack Overflow中看到有人采用上述方法成功解决问题。https://github.com/angular/angular/issues/18224

    如需要更详细的代码或有问题,请联系我

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-1-24 17:45 , Processed in 0.057054 second(s), 27 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表