【问题标题】:Interceptor for 401, Renew and Retry Angular 2401 的拦截器,更新和重试 Angular 2
【发布时间】:2016-10-04 02:36:19
【问题描述】:

角度 2 - RC5,ADAL.js


问题

所以我正在使用 adal.js 和 angular 2 对 Microsoft AD 进行身份验证。我掌握了 adal.js 的窍门,可以登录、刷新令牌、注销、获取用户等。

我现在的问题是处理扩展 Http 并创建一个自定义类,在 401 上将重试刚刚失败的请求

这基本上是我现在所拥有的:

export class HttpInterceptor extends Http {
    constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private _router: Router, private adal: IgAdal) {
       super(backend, defaultOptions);
    }

    request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
       return this.intercept(super.request(url, this.getRequestOptionArgs(options)));
    } 

    get(url: string, options?: RequestOptionsArgs): Observable<Response> {
       return this.intercept(super.get(url, this.getRequestOptionArgs(options)));
    }

    intercept(observable: Observable<Response>): Observable<Response> {
       return observable.catch((err, source) => {
         if (err.status  == 401) {   
            this.adal.acquireTokenObservable().flatMap(data=>{
                // NOT SURE WHAT TO DO HERE...
                return Observable.throw(err);
            })
         } else {
            return Observable.throw(err);
         }
      });
    }
}

当它不是 401 时,这很有效,会抛出应有的错误。现在,当我在 401 后尝试调用 super.get() 并获得了新令牌时......它不会再次尝试请求,而是出现这样的错误......

Cannot read property 'subscribe' of undefined

^^^ 我认为这与订阅请求毕竟已经返回有关。

我认为还值得指出的是,我的 main.ts 设置很好,因为拦截器至少可以工作。


我的问题是:

  • 从拦截器中重试请求是否正确?或者以后在订阅中重试请求是否更有意义。
  • 重试请求是一种好习惯,还是通知用户重试更好? (我假设这听起来有点刺耳)
  • 是否有 rxjs 函数可用于在返回值后重试? (如“acquireToken”函数中的令牌)

编辑 1

    intercept(observable: Observable<Response>): Observable<Response> {
    return observable.catch((err, source) => {
        if (err.status  == 401) {   
            return this.adal.acquireTokenObservable().flatMap(data=>{
               return observable.retry(3);
            })
        } else {
            return Observable.throw(err);
        }
    });
}

刚刚尝试了“重试”rxjs 运算符.. 似乎正在做我想做的事情。现在我的问题是……重试失败后如何将某人发送到登录页面?


这是我的第一个 stackoverflow 问题,如果不是最好的布局,我深表歉意

谢谢!!

【问题讨论】:

    标签: angular jwt rxjs adal adal.js


    【解决方案1】:

    对于任何调查此问题的人...我最终会这样做。

    intercept(observable: Observable<Response>): any {
        return observable.catch((err, source) => {
            if (err.status == 401) {
                return this.adal.acquireTokenObservable().flatMap(data=>{
                    if (data === 'User login is required') {
                        this.adal.login();
                    }
                    return observable;
                })
            } else {
                return Observable.throw(err);
            }
        });
    }
    

    返回可观察流本身而不是 .retry() 似乎做了完全相同的事情,而且只重试了 1 次。否则 .retry(1) 由于某种原因实际上会抛出 3 个单独的错误。

    this.adal.acquireTokenObservable()

    是我使用 adal.js 库返回带有新令牌的流的可观察对象。仍在处理有关重试某些请求的其他几个问题,但这是一个好的开始。

    【讨论】:

      【解决方案2】:
      1. 401 是未经授权的,因此我们不会在拦截器中重试并且请求被拒绝。如果您想重试,可以再次调用acquiretoken API。
      2. 让用户决定会更好。除非服务器已关闭(http 响应 500,503 和 504)或网络超时并且您没有收到 http 响应。在这些情况下,最好在开发人员端重试。
      3. adal.js 库中没有重试功能。如果要重试,则需要再次调用 AcquireToken API。

      【讨论】:

        猜你喜欢
        • 2021-07-05
        • 1970-01-01
        • 2021-11-12
        • 2016-08-14
        • 1970-01-01
        • 1970-01-01
        • 2018-05-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多