【问题标题】:Angular >4.3 & <5.2.3 - JWT Interceptor - Refresh TokenAngular >4.3 & <5.2.3 - JWT 拦截器 - 刷新令牌
【发布时间】:2017-12-26 00:37:43
【问题描述】:

重要的角度>4.3 &

我使用 HttpClient 并创建此拦截器来添加 jwt 令牌。 Everyting 工作完美,但我有一个不好的做法。我在 HttpClient 拦截器中使用 Http。如果我改变了

private http: Http,

private http: HttpClient

我得到这个循环错误

Cannot instantiate cyclic dependency! InjectionToken_HTTP_INTERCEPTORS ("[ERROR ->]") 

有什么想法可以让它发挥作用吗?

import {Injectable} from "@angular/core";
import {HttpEvent, HttpHandler, HttpInterceptor} from "@angular/common/http";
import {HttpRequest} from "@angular/common/http";
import {Observable} from "rxjs/Observable";
import {Http} from "@angular/http";
import {SiteService} from "../services/site.service";
import {Router} from "@angular/router";

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

constructor(
    private http: Http,
    private router: Router,
    private siteService: SiteService
) {}

refreshToken() {
    return this.http.get(this.siteService.apiDomain() + '/api/token?token=' + localStorage.getItem('JWToken'), {})
        .map((response: any) => {
            let data = response.json();
            return {
                token: data.token,
                permissions: data.permissions,
                user: data.user,
            };
        })
}

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const clonedRequest = req.clone({
        headers: req.headers.set('Authorization', 'Bearer ' + localStorage.getItem('JWToken'))
    });

    return next.handle(clonedRequest).catch((res) => {

        if (res.status === 401 || res.status === 403) {
            return this.refreshToken().flatMap((data) => {
                if (data.token !== '') {
                    localStorage.setItem('currentUser', JSON.stringify(data.user));
                    localStorage.setItem('currentUserPermissions', JSON.stringify(data.permissions));
                    localStorage.setItem('JWToken', data.token);
                } else {
                    localStorage.removeItem('currentUser');
                    localStorage.removeItem('currentUserPermissions');
                    localStorage.removeItem('JWToken');
                    this.router.navigate(['./auth/login']);
                    return Observable.throw(res);
                }
                const clonedRequestRepeat = req.clone({
                    headers: req.headers.set('Authorization', 'Bearer ' + localStorage.getItem('JWToken'))
                });
                return next.handle(clonedRequestRepeat);
            })
        } else {
            return Observable.throw(res);
        }

    });

}
}

对于那些将在项目中使用此拦截器但与当前问题无关的人来说,另一件重要的事情是至少在几秒钟内将标头设置为刷新令牌响应。

->header('Cache-Control', 'public, max-age=45')
->header('Expires', date('D, d M Y H:i:s ', time() + 45).'GMT');

【问题讨论】:

标签: angular angular-http-interceptors


【解决方案1】:

我解决了没有在构造函数中设置 authService 而是进入拦截函数。

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // Get the auth header from the service.
    const auth = this.inj.get(AuthenticationService);
    const authToken = auth.getAuthorizationToken();
    ...
}

你必须先将 Injector 添加到你的构造函数中

constructor(
            ...
            private inj: Injector
) {}

【讨论】:

    【解决方案2】:

    您也可以尝试一些小技巧来实例化该服务,例如:

    constructor(private injector: Injector) {
      setTimeout(() => {
          this.loginService = this.injector.get(LoginService);
      })
    }
    

    这样您就不会收到超出最大调用堆栈的错误。

    【讨论】:

      猜你喜欢
      • 2017-12-31
      • 2018-06-12
      • 2019-03-28
      • 1970-01-01
      • 2021-05-17
      • 2022-11-03
      • 2022-01-13
      • 2018-06-02
      • 2019-09-03
      相关资源
      最近更新 更多