Angular 角度-刷新JWT令牌(并行调用)

Angular 角度-刷新JWT令牌(并行调用),angular,angular2-jwt,Angular,Angular2 Jwt,我有一个关于刷新令牌流的问题 我试着打个电话,这是代币。令牌已过期,并发出第二个刷新令牌的请求。我正在获取响应并使用新令牌重新运行请求 在我尝试使用相同的无效令牌发出多个并行请求之前,一切都是完美的 问题是,如果我使用相同的令牌进行3次并行调用,那么第一次调用会使令牌对其他2次调用无效 我是不是在流方面做错了什么 import {Injectable} from '@angular/core'; import {Request, XHRBackend, RequestOptions, Respo

我有一个关于刷新令牌流的问题

我试着打个电话,这是代币。令牌已过期,并发出第二个刷新令牌的请求。我正在获取响应并使用新令牌重新运行请求

在我尝试使用相同的无效令牌发出多个并行请求之前,一切都是完美的

问题是,如果我使用相同的令牌进行3次并行调用,那么第一次调用会使令牌对其他2次调用无效

我是不是在流方面做错了什么

import {Injectable} from '@angular/core';
import {Request, XHRBackend, RequestOptions, Response, Http, RequestOptionsArgs, Headers} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {Router} from '@angular/router';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import {RefreshTokenService} from "../services/refreshToken.service";

@Injectable()
export class HttpService extends Http {

constructor(
    backend: XHRBackend,
    options: RequestOptions,
    private refreshTokenService?: RefreshTokenService,
    private router?: Router
) {
    super(backend, options);
}

request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {

    if (typeof url === 'string') {
        if (!options) {
            options = {headers: new Headers()};
        }
        this.setHeaders(options);
    } else {
        this.setHeaders(url);
    }

    return super.request(url, options).catch(this.catchErrors(url, options));
}

private catchErrors(url: string | Request, options?: RequestOptionsArgs) {
    return (res: Response) => {

        if (res.status === 401 || res.status === 403) {


            if ( this.refreshTokenService.wait === false ) {

                this.refreshTokenService.wait = true;
                return this.refreshTokenService.refreshToken(localStorage.getItem('JWToken'))
                    .flatMap((result: any) => {
                        // if got new access token - retry request
                        if (JSON.parse(result._body).token) {
                            localStorage.setItem('JWToken', JSON.parse(result._body).token);
                            this.setHeaders(url);
                            this.refreshTokenService.wait = false;
                            return this.request(url, options);
                        } else {
                            return Observable.throw(new Error('Can\'t refresh the token'));
                        }

                    })
            } else {
                // TODO... return this only if new token is ok
                this.setHeaders(url);
                return this.request(url, options);
            }
        } else {
            Observable.throw(res);
        }
    };
}

private setHeaders(objectToSetHeadersTo: Request | RequestOptionsArgs) {
    // add whatever header that you need to every request
    objectToSetHeadersTo.headers.set('Authorization', 'Bearer ' + localStorage.getItem('JWToken'));
}


}
从'@angular/core'导入{Injectable};
从“@angular/Http”导入{Request,XHRBackend,RequestOptions,Response,Http,RequestOptionsArgs,Headers};
从“rxjs/Observable”导入{Observable};
从'@angular/Router'导入{Router};
导入“rxjs/add/operator/catch”;
导入“rxjs/add/observable/throw”;
从“./services/refreshttoken.service”导入{refreshttokenservice};
@可注射()
导出类HttpService扩展Http{
建造师(
后端:XHRBackend,
选项:请求选项,
专用refreshTokenService?:refreshTokenService,
专用路由器?:路由器
) {
超级(后端,选项);
}
请求(url:string |请求,选项?:RequestOptionsArgs):可观察{
如果(url的类型=='string'){
如果(!选项){
选项={headers:newheaders()};
}
这个.setHeaders(选项);
}否则{
这个.setHeaders(url);
}
返回super.request(url,options).catch(this.catchErrors(url,options));
}
私有捕获错误(url:string |请求,选项?:RequestOptionsArgs){
返回(res:Response)=>{
if(res.status==401 | | res.status==403){
if(this.refreshtTokenService.wait==false){
this.refreshTokenService.wait=true;
返回此.refreshTokenService.refreshToken(localStorage.getItem('JWToken'))
.flatMap((结果:任意)=>{
//如果获得新的访问令牌-重试请求
if(JSON.parse(result.\u body.token){
setItem('JWToken',JSON.parse(result.\u body.token));
这个.setHeaders(url);
this.refreshTokenService.wait=false;
返回此.request(url、选项);
}否则{
return Observable.throw(新错误('Can't refresh the token'));
}
})
}否则{
//TODO…仅当新令牌正常时才返回此项
这个.setHeaders(url);
返回此.request(url、选项);
}
}否则{
可观察。投掷(res);
}
};
}
私有setHeader(objecttoseHeadersto:Request | RequestOptionsArgs){
//在每个请求中添加所需的标题
objectToSetHeadersTo.headers.set('Authorization','Bearer'+localStorage.getItem('JWToken'));
}
}

返回的错误是什么?更新代码。我需要的是概念,不是代码。一种方法是以某种方式存储调用,直到我有了新的令牌,或者将其放入interval循环,直到我有了有效的令牌,并向我展示可能的代码。您是否可以在teamviewer中使用?是的,我曾想过尝试实现一些队列,这些队列将暂停,直到收到新的有效令牌。让我知道你的进展:)我只是添加代码。。。我需要TODO部分(注释)返回的错误是什么?更新代码。我需要的是概念,不是代码。一种方法是以某种方式存储调用,直到我有了新的令牌,或者将其放入interval循环,直到我有了有效的令牌,并向我展示可能的代码。您是否可以在teamviewer中使用?是的,我曾想过尝试实现一些队列,这些队列将暂停,直到收到新的有效令牌。让我知道你的进展:)我只是添加代码。。。我需要TODO部分(注释)