所以我有我的身份验证服务 AuthService ,基本上有两种方法,一种是从服务器获取新令牌,给定用户名和密码,另一种是检索当前存储的令牌必要时在过程中刷新令牌。 两者显然都依赖于 HttpClient 。也就是说, AuthService 依赖于 HttpClient 。让我们记住这一点。
另一项"服务"是 HttpInterceptor ,我想拦截除 AuthService 以外的所有传出请求以添加授权标题(它正在获取)现在很脏)。为了构成标题,我们需要一个令牌,我们可以从 AuthService 获得。也就是说, AuthInterceptor (我的拦截器的名称)依赖于 AuthService 。据我所知, HttpClient 依赖于所有 HTTP_INTERCEPTORS 。
关于如何打破这个圈子的任何想法或建议? 有没有办法让 Auth服务的 HttpClient 独立于 AuthInterceptor ?或者这是一个坏主意? (另外第三个功能将被添加到 AuthService ,用于将用户注销,其请求将被截获并且还将Authorization标头添加到其中)
到目前为止,我发现了类似的issue,但是解决方法表明我的问题没有解决,现在我在发送任何请求之前在引导过程中得到无限递归。我已经处理了拦截登录和令牌刷新请求以避免this的情况,所以据我所知,这不是问题所在。 这是plunk,其中包含我的代码概述。
从插件中摘录:
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
private auth: AuthService;
constructor(inj: Injector) {
this.auth = inj.get(AuthService);
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Ignore if login or refresh request
if (req.url.includes('login')) {
return next.handle(req);
}
console.log('Intercepting request...');
return this.auth.getToken().map(token => {
const authHeader = 'Bearer ' + token;
const authReq = req.clone({setHeaders: {Authorization: authHeader}});
return authReq;
}).concatMap(newReq => next.handle(newReq));
}
}
答案 0 :(得分:6)
尝试使用超时设置this.auth
:
constructor(private injector: Injector) {
setTimeout(() => {
this.auth = this.injector.get(AuthService);
})
}
您已链接到的错误报告已更新,并提供了替代解决方法(在拦截函数中检索AuthService /而不是在构造函数中设置它):https://github.com/angular/angular/issues/18224#issuecomment-316957213
答案 1 :(得分:4)
更新08/02/2018 - angular 5.2.3
只是对此的更新:这是在角度5.2.3
中修复的https://github.com/angular/angular/blob/master/CHANGELOG.md#bug-fixes-2
因此,您可以在HttpInterceptors中直接注入依赖于HttpClient的服务
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private auth: AuthService)
答案 2 :(得分:1)
我在使用Angular 6.1.10时遇到了相同或相似的问题。我只是自己在需要注入HttpInterceptor的服务中实例化HttpClient:
@Injectable()
export class AuthService {
private http: HttpClient;
constructor(httpBackend: HttpBackend) {
this.http = new HttpClient(httpBackend);
}
}
这打破了我的无限循环问题。
答案 3 :(得分:0)
我的问题是在注入到 HttpInterceptor 的服务构造函数中使用了 HttpClient。
export class SettingsService {
constructor(
private http: HttpClient,
) {
this.http.get(...).subscribe() => {
...
});
}
}
export class AppInterceptor implements HttpInterceptor {
constructor(
private settingsS: SettingsService,
) { }
...
...
}