Я исправил свою проблему, выполнив setTimeout в конструкторе перехватчика с задержкой 0 мс, что делает вызовы, необходимые для входа в мое приложение. В противном случае я бы получил ошибку циклической зависимости. Затем я подписался на эти вызовы в перехватчике, чтобы получить значения.
Чтобы предотвратить неправильный запрос от графа Microsoft / me api, я добавил проверку, начался ли запрос с URL-адреса веб-интерфейса. Я выполняю код для добавления параметров, только если это запрос API.
Вот так выглядит мой перехватчик:
import { Injectable, Injector } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpClient, HttpBackend } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { apiConfig } from './app-config';
@Injectable({
providedIn: 'root'
})
export class IdentityInfoInterceptorService implements HttpInterceptor {
msProfile: any;
ipAddress: string;
reference = "";
constructor(private injector: Injector, private httpBackend: HttpBackend, private http: HttpClient) {
setTimeout(() => {
this.getMsProfile()
.subscribe((profile) => {
console.log("setting profile to " + (profile as any)?.userPrincipalName);
this.msProfile = profile;
});
this.getIpAddress()
.subscribe((ip) => {
console.log("setting ip to " + (ip as any)?.ip);
this.ipAddress = (ip as any)?.ip;
});
}, 0);
}
getMsProfile() {
if (this.msProfile) {
return of(this.msProfile);
}
return this.http.get(apiConfig.graphMeEndpoint);
}
getIpAddress() {
if (this.ipAddress) {
return of(this.ipAddress);
}
return this.http.get(apiConfig.ipEndpoint);
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// check needs to be there in order to get the Microsoft profile end point without getting bad request.
if (req.url.startsWith(apiConfig.webApi)) {
req = req.clone({
setParams: {
userName: this.msProfile?.userPrincipalName ?? "undefined",
externalIpAddress: this.ipAddress ?? "undefined"
}
});
}
return next.handle(req);
}
}
Причина, по которой существуют функции для получения профиля и IP-адреса с возвращаемым значением (), чтобы я мог подождать, пока эти значения будут «кэшированы», прежде чем я введу любой маршрутизатор-выход приложения с * ngIf в шаблоне для маршрутизатора-выхода.
Поэтому у меня есть (частично показанный) код ниже в моем файле AppComponent (точка входа в приложение):
ngOnInit() {
this.identityInfoService.getMsProfile().subscribe(
() => {
this.identityInfoService.getIpAddress().subscribe(
() => {
this.showLoading = false;
},
(error) => {
this.showLoading = false;
}
);
}
);