【问题标题】:Unable to inject Service into HttpInterceptor properly无法将服务正确注入 HttpInterceptor
【发布时间】:2019-06-03 16:31:38
【问题描述】:

我正在使用 Ionic 4 和 Angular 7。我正在尝试拦截 HTTP 请求并向标头添加一个令牌。问题是当我尝试从AuthService 检索它时,token 始终为空。我已将AuthService 添加到TokenInterceptor 构造函数,并注入AuthService。它们都不起作用。我究竟做错了什么?

AuthService.ts

@Injectable({
    providedIn: 'root'
})
export class AuthService
{

  public token: string;
  public refreshToken: string;

  constructor
  (
    private http: HttpClient,
    private storage: StorageService,
  )
  {

    this.API_URL      = constants.API_URL;
    this.OAUTH_URL    = constants.AUTH_URL;

      this.storage.getTokens().then(tokens => {
        this.token            = tokens.access_token;
        this.refreshToken     = tokens.refresh_token;
      });

  }
}

TokenInterceptorService

@Injectable()
  export class TokenInterceptorService implements HttpInterceptor
  {

    constructor
    (
        private auth: AuthService,
    )
    {
    }

    setHeaders(req: HttpRequest<any>, token: string): HttpRequest<any> {
        return req.clone({
          setHeaders: {
              Authorization: `Bearer ${token}`,
              'Content-Type': 'application/json',
              'Accept': 'application/json',
          }
        });
    }

    public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
    {

        console.log("token int", this.auth);    // I CAN SEE TOKEN HERE  
        console.log("token int2", this.auth.token); // TOKEN IS UNDEFINED 
        return next.handle(this.setHeaders(req, this.auth.token));
     }
}

App.Module.ts 中的Providers 数组

提供者:[ // .... 身份验证服务, API服务, { 提供:HTTP_INTERCEPTORS, useClass: TokenInterceptorService, 多:真, }, ]

我也尝试过注入 AuthService 但它不起作用

@Injectable()
export class TokenInterceptorService implements HttpInterceptor
{

private auth;

constructor
(
    private injector: Interjector
)
{
  this.auth = this.injector.get(AuthService);
}

  setHeaders(req: HttpRequest<any>, token: string): HttpRequest<any> {
      return req.clone({
        setHeaders: {
            Authorization: `Bearer ${token}`,
            'Content-Type': 'application/json',
            'Accept': 'application/json',
        }
      });
  }

  public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
  {

      console.log("token int", this.auth); // I CAN SEE THE TOKEN HERE ALONG WITH ALL OF THE OTHER VARIABLES AND DECLERATIONS IN `AUTHSERVICE`.  
      console.log("token int2", this.auth.token); // TOKEN IS UNDEFINED 
      return next.handle(this.setHeaders(req, this.auth.token));
   }
}

我还尝试添加 AuthService 作为 TokenInterceptorService 的依赖项

providers: [
  // .... 
  AuthService,
  APIService,
  {
    provide: HTTP_INTERCEPTORS,
    useClass: TokenInterceptorService,
    multi: true,
     deps: [AuthService],
  },
  // ....
]

【问题讨论】:

  • 一方面,您似乎在 auth 服务(需要 HttpClient)、HttpClient(需要拦截器)和拦截器(需要 auth 服务)之间存在循环依赖关系。但是您能否详细说明 “我可以在这里看到令牌” 的含义?
  • 我不确定如何解决循环依赖。如果我登录this.auth,我可以看到AuthService 中的所有变量,包括token

标签: angular ionic-framework


【解决方案1】:

AuthService 是个坏主意。因为它是单例,所以令牌值无法同步,而 Storage.getTokens 是同步方法,在使用之前您也无法确定 AuthService.Token 是否准备好。其他,1:更新后无法获取新Token; 2:你不知道用户已经注销。

所以,请使用 setHeaders 方法更好。在我的来源中,逻辑是这样的:

//TokenInterceptorService
async setHeaders(url) {
  let baseHeader = {/*default values*/};
  if (url in sign-in, register, logout, home or other public api) {
    return baseHeader;
  }
  let token = {};
  await storage.getToken().then(tokenData => {
    token = tokenData;
  };
  baseHeader.token = token;
  return baseHeader;
}

【讨论】:

  • 抱歉在 setHeaders 方法中做了什么?
  • 我只是在那里添加了伪代码,希望对您有所帮助。
猜你喜欢
  • 2019-03-08
  • 2019-09-19
  • 2017-06-27
  • 2018-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多