无法将服务正确地注入HttpInterceptor

时间:2019-01-08 23:03:20

标签: angular ionic-framework

我正在使用Ionic 4和Angular7。我试图拦截HTTP请求并将令牌添加到标头中。问题是,当我尝试从token检索AuthService时,它总是为空。我向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数组

提供者:[   // ....   AuthService,   APIService,   {     提供: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],
  },
  // ....
]

1 个答案:

答案 0 :(得分:1)

AuthService是个坏主意。由于它是单例,因此令牌值无法同步,并且Storage.getTokens是sync方法,因此在使用它之前,您也无法确定AuthService.Token已准备就绪。还有其他的1:如果更新了,您将无法获得新令牌; 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;
}