Сообщение об ошибке Angular 5 HTTP Interceptors
У меня проблема с моими Angular 5: HTTP Interceptors. Я новичок здесь, поэтому, пожалуйста, будьте терпеливы, когда я узнаю, как все это работает. Это мое сообщение об ошибке:
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');
}
}
4 ответа
Вот как я и коллега исправили это:
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
}
}
В основном пришлось внедрить таким образом сервис аутентификации, а не как раньше.
У вас есть сервисы, зависящие друг от друга, попробуйте это, чтобы вручную ввести AuthenticationService в ваш перехватчик и разорвать круговую зависимость
constructor(injector: Injector) {
this.authService= injector.get(AuthenticationService)
}
или вы внедряете его в конструктор функции перехвата (инжектор: Инжектор) {} перехват (req: HttpRequest <любой>, следующий: HttpHandler): Observable
const auth = this.injector.get(AuthenticationService);
Итак, причина, по которой вы получаете это из-за кода ниже
@Injectable()
export class AuthenticationService {
constructor(private http: HttpClient, private router: Router) {
this.isAuthenticatedSubject.next(false);
}
}
Здесь сервис HttpClient и Маршрутизатор вызывает проблему для вас. Таким образом, чтобы решить вашу проблему, вам нужно разделить свой сервис на меньший код и разделить их задачи. Ниже приведены шаги, которые вы должны выполнить, чтобы решить проблему
- Держите службы вызова http вне службы аутентификации
- делиться информацией о токене и пользователе, используя другой одноэлементный сервис, т.е. AuthService, который не имеет никакой зависимости.
- Инициировать события из службы вызова http, а не из AuthService
- Внедрить AuthService в службу вызова http и перехватчик для обмена данными
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);
}
}