1

次の認証サービスがあります。

@Injectable()
export class AuthService {

  //...

  constructor(private http: Http, private router: Router) {
    //...
  }

  public login(username: string, password: string): Observable<boolean> {
    // perform login
  }

  public logout() {
    // perform cleanup
    this.router.navigateByUrl('/login');
  }
}

そして、次のHttpインターセプターファクトリー:

@Injectable()
class MyHttpInterceptor extends Http {

  constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private authService: AuthService) {
    super(backend, defaultOptions);
  }

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

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

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

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

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

  getRequestOptionArgs(options?: RequestOptionsArgs): RequestOptionsArgs {
    if (options == null) {
      options = new RequestOptions();
    }
    if (options.headers == null) {
      options.headers = new Headers();
    }
    // add headers required by our backend
    return options;
  }

  intercept(observable: Observable<Response>): Observable<Response> {
    return observable.catch((err, source) => {
      if (err.status == 401) {
        this.authService.logout();
        return Observable.empty();
      } else {
        return Observable.throw(err);
      }
    });

  }
}

export function myHttpInterceptorFactory(backend: ConnectionBackend, options: RequestOptions, authService: AuthService): MyHttpInterceptor {
  return new MyHttpInterceptor(backend, options, authService);
}

基本的に、ここでの要件は、バックエンドからステータス 401 の応答を受信した場合、ログアウト手順を開始する必要があるということです。

App モジュールでの設定は次のとおりです。

@NgModule({
  imports: [
    HttpModule,
    //...
  ],
  declarations: [
    AppComponent,
    //...
  ],
  providers: [
    {
      provide: Http,
      useFactory: myHttpInterceptorFactory,
      deps: [XHRBackend, RequestOptions, AuthService]
    },
    AuthService,
    //...
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
}

Httpこれにより、インターセプターが必要とする循環依存エラーが発生しますAuthServiceが、AuthService必要Httpです。

Error: Provider parse errors:
Cannot instantiate cyclic dependency! Http: in NgModule AppModule in ./AppModule

を使用forwardRefして注入しようとしHttpましAuthServiceたが、何も変わりませんでした。

再構築する方法についての助けは素晴らしいでしょう。

4

1 に答える 1