Angular 5 条 HTTP 拦截器错误消息

Angular 5 HTTP Interceptors error message

我的 Angular 5: HTTP 拦截器有问题。我是新来的所以请耐心等待我了解所有这些是如何工作的。这是我的错误信息:

 compiler.js:19514 Uncaught Error: Provider parse errors:
 Cannot instantiate cyclic dependency! InjectionToken_HTTP_INTERCEPTORS 
 ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1

这是我的拦截器代码:

import {Injectable} from '@angular/core';
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from'@angular/common/http';
import {Observable} from 'rxjs/Observable';
import {AuthenticationService} from '../_services/authentication.service';



 @Injectable()
 export class AuthInterceptor implements HttpInterceptor {

constructor(private authService: AuthenticationService) {}

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

    this.authService.id_token = localStorage.getItem('access_token');

    // Retrieving the JWT string from Local Storage directly

    if (this.authService.id_token) { // We are checking if the JWT is present

        const cloned = req.clone({
          headers: req.headers.set('Authorization', 'Bearer ' + this.authService.getToken(this.authService.username, this.authService.password))

        });
        return next.handle(cloned); // If the JWT is not present, then the request goes through to the server unmodified

    } else {

        return next.handle(req); // If the JWT is present, then we will clone the HTTP headers, and add an extra Authorization header, which will contain the JWT
    }
   }
}

我正在导入身份验证服务,但不知道还能做什么,我已经尝试注入它,但它不起作用。请帮忙。

          @NgModule({
         declarations: [
         AppComponent,
         NavbarComponent,
         hatitPageComponent,
         hatitLitePageComponent,
         hatitbodyComponent,
         hatitLitebodyComponent,
         MeterqueryComponent,
         MeterlinesideComponent,
         MeterloadsideComponent,
         MeterstatusComponent,
         CommstatusComponent,
         MeterlistComponent,
         MessagecenterComponent,
         FooterComponent,
         WhatsnewComponent,
         MeterresultsComponent,
         DefaultareaComponent,
         InstructionsComponent,
         AuthComponent,
         HomeComponent,
        ],
        imports: [
         BrowserModule,
         FormsModule,
         RoutingModule,
         HttpClientModule,
         BrowserAnimationsModule,
         MatProgressSpinnerModule,
             ],
       providers: [
          ClockService,
          MessageCenterService,
          MeterService,
          DaqService,
          AuthenticationService,
          AuthGuard,
          hatitGuard,
          hatitLiteGuard,
          VersionService,
          {provide: HTTP_INTERCEPTORS , useClass: AuthInterceptor, multi: true}
          ],
        bootstrap: [AppComponent]
                })
        export class AppModule {
     }


import { Injectable} from '@angular/core';
import { Observable} from 'rxjs/Observable';
import {HttpParams, HttpHeaders, HttpClient} from '@angular/common/http';
import { AdGroup } from '../_models/adgroup.model';
import { adGroupsEnum } from '../_enums/adgroups.enum';
import { Router } from '@angular/router';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

  @Injectable()
  export class AuthenticationService {

    username: any;
    password: any;
    loggedInUsername: string;
    loggedInUserADGroups: string[] = [];
    loggedInUserADGroupModels: AdGroup[] = [];
    // tokenExpirationTimer: any;

    isAuthenticated = false;
    isAuthenticatedSubject: BehaviorSubject < boolean > = new BehaviorSubject(false);

           authApiEndpoint = '';

           hatitCall = '';
           // userAuthURL = '';

           id_token = null;
           refresh_token = null;
           access_token = null;
           // tokenRefreshInterval: any;

           consumer_key_empim = '';
           consumer_secret_empim = '';

           constructor(private http: HttpClient,
          private router: Router) {
             this.isAuthenticatedSubject.next(false);
           }

           ADDGroupMapper(adGroup: string) {
             const adGroupEnumElem = adGroupsEnum[adGroup];
             return new AdGroup(
               adGroupEnumElem['adGroupName'],
               adGroupEnumElem['adGroupEnv'],
               adGroupEnumElem['adGroupApp']
             );
           }

           getUserADDGroups(userName) {
             this.loggedInUserADGroups = [];
             this.loggedInUserADGroupModels = [];
             const url = this.getAuthDSEndPoint();
             const params = new HttpParams()
               .set('lanId', userName)
               .set('domain', this.getUserDomain());
             console.log(url);
             return this.http.get(url, {
               params: params,
               responseType: 'text'
             });
           }


            getToken(username, password): Observable < any > {
                const headers = new HttpHeaders({
                'Content-Type': 'application/x-www-form-urlencoded',
                'Authorization': 'Basic ' + btoa(this.consumer_key_emp + ':' + this.consumer_secret_empim)
                });
                if (username && password) {

                let formData = 'username=' + encodeURIComponent(username) + '&password=' + encodeURIComponent(password)
                    + '&scope=openid msso&grant_type=password';

                return this.http.post(this.getAuthEndPoint(), formData, {
                    headers: headers,
                });
                }
                return null;
            }


                getBackEndRefreshToken() {
                    const headers = new HttpHeaders({
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'Authorization': 'Basic ' + btoa(this.consumer_key_emp + ':' + this.consumer_secret_empim)
                    });
                    const formData = 'grant_type=refresh_token&refresh_token=';
                    return this.http.post(this.getAuthEndPoint(), formData)
                    .map(response => response)
                    .catch(error => {
                        this.clearSession();
                        this.router.navigate(['/login']);
                        return Promise.reject(error);
                    }).subscribe(response => {

                        this.setAccessToken(this.access_tokenim);
                        this.setRefreshToken(this.refresh_tokenim);

                        localStorage.setItem('access_token', this.access_tokenim);
                        localStorage.setItem('refresh_token', this.refresh_tokenim);
                    });
                }

                loginUser(username, password, id_token): Observable<any> {
                    this.id_token = id_token;
                    const headers = new Headers({
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'Authorization': 'Basic ' + btoa(this.consumer_key_emp + ':' + this.consumer_secret_empim)
                    });
                    const header = new Headers({ headers: headers });
                    this.getBackEndRefreshToken();
                    if (username && password) {
                    const formData = 'username=' + encodeURIComponent(username) + '&password=' + encodeURIComponent(password)
                        + '&scope=openid msso&grant_type=password';

                    return this.http.post(this.hatitCall, formData).map(res => res);
                    }
                    return null;
                }

                // loginUser(token):  Observable<any> {
                //   this.id_token = token;
                //   const headers = new HttpHeaders({
                //     'Content-Type': 'application/x-www-form-urlencoded',
                //     'Authorization': 'Basic ' + btoa(this.consumer_key_emp + ':' + this.consumer_secret_empim)
                //     });
                //     const options  = new RequestOptions({headers: headers});
                //   const formData = 'username=' + encodeURIComponent(this.username) + '&password=' + encodeURIComponent(this.password)
                //     + '&scope=openid msso&grant_type=password';
                //       return this.http.post(this.hatitCall, formData, options).map(res => res);
                // }

                logOut(): void {
                    this.clearSession();
                }

                isUserAuthenticated(): boolean {
                    return this.isAuthenticated;
                }

                hashatitAppAccess() {
                    const appLookUp = 'hatit';
                    // console.log('Checking for hatit Access');
                    if (this.loggedInUserADGroupModels.length > 0) {
                    for (const adg of this.loggedInUserADGroupModels) {
                        if (adg.adGroupApp === appLookUp) {
                        return true;
                        }
                    }
                    }
                    return false;
                }

                hashatitLiteAppAccess() {
                    const appLookUp = 'hatitLite';
                    // console.log('Checking for hatitLite Access');
                    if (this.loggedInUserADGroupModels.length > 0) {
                    for (const adg of this.loggedInUserADGroupModels) {
                        if (adg.adGroupApp === appLookUp) {
                        return true;
                        }
                    }
                    }
                    return false;
                }
                clearSession() {
                    sessionStorage.clear();
                }

                getRefreshToken() {
                    return sessionStorage.getItem('refresh_token');
                }

                setAccessToken(token) {
                    sessionStorage.setItem('access_token', token);
                }
                setRefreshToken(token) {
                    sessionStorage.setItem('refresh_token', token);
                }
                getUserDomain() {
                    return 'NAM';
                }

                getAuthEndPoint() {
                    return this.authApiEndpoint + this.hatitCall;
                }

                getAuthDSEndPoint() {
                    return this.authApiEndpoint + this.hatitCall;
                }
                getAccessToken() {
                    return sessionStorage.getItem('access_token');
                }
                }

你有相互依赖的服务,试试这个在你的拦截器中手动注入 AuthenticationService 并打破循环依赖

 constructor(injector: Injector) {
   this.authService= injector.get(AuthenticationService)
}

或者你将它注入到你的拦截函数中 构造函数(注入器:注入器){} 拦截(req: HttpRequest < any > , next: HttpHandler): Observable < HttpEvent <任何>> {

const auth = this.injector.get(AuthenticationService);

好的,你得到的原因是因为下面的代码

@Injectable()
export class AuthenticationService {
    constructor(private http: HttpClient, private router: Router) {
             this.isAuthenticatedSubject.next(false);
    }
}

此处 HttpClientRouter 服务导致了您的问题。因此,要解决您的问题,您需要将您的服务拆分成更小的代码并分离它们的关注点。以下是您应该遵循的解决问题的步骤

  1. 让http调用服务远离认证服务
  2. 使用另一个单例服务共享令牌和用户信息,即没有任何依赖性的 AuthService。
  3. 从 http 调用服务而不是 AuthService 触发事件
  4. 将AuthService注入http调用服务&拦截器共享数据

以下是我和一位同事修复它的方法:

import { Injectable, Injector } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from 
'@angular/common/http';
import {Observable} from 'rxjs/Observable';
import {AuthenticationService} from '../_services/authentication.service';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
private authService: AuthenticationService;

  constructor(private inj: Injector) {
   }

intercept(req: HttpRequest<any>, next: HttpHandler): 
Observable<HttpEvent<any>> {
 if (req.url.includes('token')) {
return next.handle(req);
}

this.authService = this.inj.get(AuthenticationService);

 const cloned = req.clone({
headers: req.headers.set('Authorization', 'Bearer ' + 
this.authService.getAccessToken())
});

 return next.handle(cloned); // If the JWT is not present, then the 
 request goes through to the server unmodified
}

}

基本上必须以这种方式注入身份验证服务,而不是我以前的方式。

import { HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { AccountService } from '../account.service';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

  constructor(private auth: AccountService) { }

  intercept(req: HttpRequest<any>, next: HttpHandler) {
    // Get the auth token from the service.
   const authToken = this.authToken.getToken();

    // Clone the request and replace the original headers with
    // cloned headers, updated with the authorization.
    if (authToken) {
      const authReq = req.clone({
        headers: req.headers.set('Authorization', "Bearer " + authToken ?? "")
      });// send cloned request with header to the next handler.
      return next.handle(authReq);
    }
    return next.handle(req);

  }
}