首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在HttpInterceptor mergeMap之间导航时避免多个mergeMap调用?

如何在HttpInterceptor mergeMap之间导航时避免多个mergeMap调用?
EN

Stack Overflow用户
提问于 2018-10-12 13:58:29
回答 1查看 728关注 0票数 1

我使用两个JWT令牌-刷新令牌(7天后到期)和访问令牌( 15分钟后到期)。它们存储在httpOnly cookie上,可以通过服务器访问。刷新方法对新令牌进行签名并将其存储在cookie上。我需要在每次请求之后检查这些令牌是否过期,如下所示:

代码语言:javascript
复制
@Injectable()
export class AuthInterceptor implements HttpInterceptor {

    constructor(private authService: AuthService, private cookieService: CookieService) { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
            const expirationToken = this.cookieService.get('tokenexp'); // access token expiration
            const expirationTokenRefresh = this.cookieService.get('tokenrefexp'); // refresh expiration
            
            // refresh token -> access token -> original request
            return of(Number(expirationTokenRefresh) < Date.now()).pipe(
              mergeMap(expire => expire
                ? this.authService.refreshTokenRefresh()
                : of(Number(expirationToken) < Date.now())
              ),
              mergeMap(expire => expire
                ? this.authService.refreshToken()
                : of(true)
              ),
              mergeMap(ok => next.handle(req.clone({ withCredentials: true })))
            );
    }

}

// auth service
refreshToken() {
  return this.http.get(`${BACKEND_URL}/refreshtoken`);
}
refreshTokenRefresh() {
  return this.http.get(`${BACKEND_URL}/refreshtokenref`);
}

我可以发送一个请求来刷新一个令牌,然后发送另一个请求来刷新第二个令牌,最后发送一个带有更新cookie的原始请求。总之,我可能需要在原始请求之前发送请求。

问题是:每次发出请求时,都会有一个请求循环到AuthInterceptor。请求一和二(令牌)不应该调用AuthInterceptor

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-15 14:34:38

如果请求url用于令牌,则执行条件检查以跳过拦截器。

代码语言:javascript
复制
@Injectable()
export class AuthInterceptor implements HttpInterceptor {

    constructor(private authService: AuthService, private cookieService: CookieService) { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
            if(req.url===`${BACKEND_URL}/refreshtoken` || req.url ===`${BACKEND_URL}/refreshtokenref`)
              return next.handle(req.clone({ withCredentials: true }))
            
            const expirationToken = this.cookieService.get('tokenexp'); // access token expiration
            const expirationTokenRefresh = this.cookieService.get('tokenrefexp'); // refresh expiration
            
            // refresh token -> access token -> original request
            return of(Number(expirationTokenRefresh) < Date.now()).pipe(
              mergeMap(expire => expire
                ? this.authService.refreshTokenRefresh()
                : of(Number(expirationToken) < Date.now())
              ),
              mergeMap(expire => expire
                ? this.authService.refreshToken()
                : of(true)
              ),
              mergeMap(ok => next.handle(req.clone({ withCredentials: true })))
            );
    }

}

// auth service
refreshToken() {
  return this.http.get(`${BACKEND_URL}/refreshtoken`);
}
refreshTokenRefresh() {
  return this.http.get(`${BACKEND_URL}/refreshtokenref`);
}

请务必同意@新安,拦截器有时可能是一个更大的问题。创建您自己的http服务可能更好

代码语言:javascript
复制
class HttpService{
   constructoer(private _http:HttpClient)

   preIntercept(url,options){
     this._http.get(tokenUrl).pipe(
       map(res=>{
           //do your stuff
            return {url,options}
        }))

}

get(url,options={}){
    return this.preIntercept(url,options).pipe(
    mergeMap(({url,options})=>this._http.get(url,options))
}

}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52781145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档