Angular 角度2+;HttpIntercept:在返回intercept函数之前,等待来自服务器的令牌
我知道这个问题以前是以一种方式/形式/形式解决的,但我已经复习了我能找到的所有问题和答案,仍然不知道如何解决这个问题 HttpIntercept.intercept必须返回next.handle(请求)。但是,我需要它等待(我知道“wait”在前端是一个肮脏的词)承载令牌从服务器返回,然后才能返回。我一生都找不到一个模式来实现这一点。在我们到达服务器获取承载令牌之前,拦截函数无法返回 如果已经回答了这个问题,我很抱歉,请为我提供相应答案的链接 非工作示例(函数在附加令牌之前返回):Angular 角度2+;HttpIntercept:在返回intercept函数之前,等待来自服务器的令牌,angular,rxjs,Angular,Rxjs,我知道这个问题以前是以一种方式/形式/形式解决的,但我已经复习了我能找到的所有问题和答案,仍然不知道如何解决这个问题 HttpIntercept.intercept必须返回next.handle(请求)。但是,我需要它等待(我知道“wait”在前端是一个肮脏的词)承载令牌从服务器返回,然后才能返回。我一生都找不到一个模式来实现这一点。在我们到达服务器获取承载令牌之前,拦截函数无法返回 如果已经回答了这个问题,我很抱歉,请为我提供相应答案的链接 非工作示例(函数在附加令牌之前返回): 导出类令牌拦
导出类令牌拦截器实现HttpInterceptor{
构造函数(私有身份验证:AuthenticationService){}
拦截(请求:HttpRequest,下一步:HttpHandler):可观察{
let令牌:字符串;
this.auth.getToken().subscribe(响应=>{
令牌=响应['access_token'];
request=request.clone({
集合标题:{
授权:`Bearer${token}`
}
});
});
下一步返回。处理(请求);
}
}
当您的请求是异步的时,正在同步调用您的处理程序
由于您需要返回一个可观察值,请查看rxjs中的flatMap
/switchMap
操作符,它看起来像:
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let token: string;
return this.auth.getToken().flatMap(response => {
token = response['access_token'];
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
return next.handle(request);
});
}
export class TokenInterceptor implements HttpInterceptor {
constructor(private auth: AuthenticationService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.auth.getToken()
.map(response => request.clone({setHeaders: {Authorization: `Bearer ${response['access_token']}`}}))
.switchMap(request => next.handle(request));
}
}
intercept(请求:HttpRequest,下一步:HttpHandler):可观察{
let令牌:字符串;
返回此.auth.getToken().flatMap(响应=>{
令牌=响应['access_token'];
request=request.clone({
集合标题:{
授权:`Bearer${token}`
}
});
下一步返回。处理(请求);
});
}
使用开关映射
从另一个可观察
返回可观察
export class TokenInterceptor implements HttpInterceptor {
constructor(private auth: AuthenticationService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let token: string;
return this.auth.getToken().switchMap(response => {
token = response['access_token'];
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
return next.handle(request);
});
}
}
导出类令牌拦截器实现HttpInterceptor{
构造函数(私有身份验证:AuthenticationService){}
拦截(请求:HttpRequest,下一步:HttpHandler):可观察{
let令牌:字符串;
返回此.auth.getToken().switchMap(响应=>{
令牌=响应['access_token'];
request=request.clone({
集合标题:{
授权:`Bearer${token}`
}
});
下一步返回。处理(请求);
});
}
}
尝试返回可观察的已完成函数:
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let token: string;
this.auth.getToken().subscribe(response => {
token = response['access_token'];
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
},
err => { console.log(err) },
() => return next.handle(request) // this is called after the completion of observable
);
}
}
intercept(请求:HttpRequest,下一步:HttpHandler):可观察{
let令牌:字符串;
this.auth.getToken().subscribe(响应=>{
令牌=响应['access_token'];
request=request.clone({
集合标题:{
授权:`Bearer${token}`
}
});
},
err=>{console.log(err)},
()=>return next.handle(request)//在observable完成后调用
);
}
}
我能想到类似这样的事情:
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let token: string;
return this.auth.getToken().flatMap(response => {
token = response['access_token'];
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
return next.handle(request);
});
}
export class TokenInterceptor implements HttpInterceptor {
constructor(private auth: AuthenticationService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.auth.getToken()
.map(response => request.clone({setHeaders: {Authorization: `Bearer ${response['access_token']}`}}))
.switchMap(request => next.handle(request));
}
}
导出类令牌拦截器实现HttpInterceptor{
构造函数(私有身份验证:AuthenticationService){}
拦截(请求:HttpRequest,下一步:HttpHandler):可观察{
返回this.auth.getToken()
.map(response=>request.clone({setHeaders:{Authorization:`Bearer${response['access\u token']}}}}))
.switchMap(请求=>next.handle(请求));
}
}
虽然我不确定它是否会起作用。如果你发布了你的代码,那会很有帮助。更不用说帖子上说代币来自哪里了server@VincentNguyen令牌是由服务器生成的。请尝试将返回放在subscribe的第三个回调参数中。好的,我已经考虑过这一点,但是要实现HttpInterceptor接口,intercept函数必须返回一个可观察值。我应该只返回一个“虚拟”可观察对象吗?这会导致请求在拦截器完成其工作之前发出吗?是的,我完全没有意识到这似乎是一项非常常见的任务(从服务器获取令牌并将其附加到API调用中)。我感到惊讶的是,我很难解决或找到一个现有模式。@SeanIvins我在应用程序中所做的是先获取令牌并将其存储在localstorage中……但让我试着为您编写一个答案,让您尝试编译它,因为该方法没有返回anything@J.Pichardo陛下not SURE return next.handle只返回匿名函数,而不是截取函数那么当令牌过期时你该怎么办?这是一个更清晰的答案。这样你就可以去掉本地
令牌
变量This.auth.getToken()需要将一个可观察的(httpClient.post)not开关映射返回到next.handle(请求)
应将可观察的类型更改为可观察的
,至少按照我的想法。返回下一步。handle(请求)返回switchMap中的函数,而不是截取函数yes,但返回此函数。auth.getToken().switchMap()
=>这是一个可观察的
很抱歉错过了它。好的,那么switchMap将返回它的参数返回的值?即将继续模拟实现。我甚至还没有完成这项工作来测试它。switchMap
将返回下一步。句柄(请求)
,这意味着可观察的