2016-02-09 19 views
7

我想從一個地方檢查我所有的http響應。例如身份驗證狀態。如果回覆表示用戶沒有進行身份驗證,我想重定向或其他東西。有沒有辦法做到這一點。如何編寫AngularJS 2的http攔截器?

+1

你應該看看這個文檔https://github.com/angular/http/issues/80。 Angular2 Http攔截器和變壓器現在正在進行深入討論。如果你需要重定向一個未經身份驗證的用戶,我會建議你做那個服務器端(除了SPA) – Antoine

回答

5

在這裏,我們去

創建這樣

export const JWT_RESPONSE_HEADER = 'X-Auth-Token'; 

@Injectable() 
export class AuthHttp extends Http { 
    constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) { 
    super(backend, defaultOptions); 
    } 

    request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> { 
    const request = super.request(url, this.appendAuthHeader(options)); 
    request.map(this.saveToken); 
    return request; 
    } 

    get(url: string, options?: RequestOptionsArgs): Observable<Response> { 
    const request = super.get(url, this.appendAuthHeader(options)); 
    request.map(this.saveToken); 
    return request; 
    } 

    post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> { 
    const request = super.post(url, body, this.appendAuthHeader(options)); 
    request.map(this.saveToken); 
    return request; 
    } 

    put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> { 
    const request = super.put(url, body, this.appendAuthHeader(options)); 
    request.subscribe(this.saveToken); 
    return request; 
    } 

    delete(url: string, options?: RequestOptionsArgs): Observable<Response> { 
    const request = super.delete(url, this.appendAuthHeader(options)); 
    request.map(this.saveToken); 
    return request; 
    } 

    private appendAuthHeader(options?: RequestOptionsArgs): RequestOptionsArgs { 
    let mergedOptions: RequestOptionsArgs; 
    if (!options) { 
     mergedOptions = { headers: new Headers() }; 
    } else { 
     mergedOptions = options; 
    } 
    const token = localStorage.getItem(JWT_RESPONSE_HEADER); 
    const isTokenSet = mergedOptions.headers.has('Authorization'); 
    if (token && !isTokenSet) mergedOptions.headers.append('Authorization', `Bearer ${token}`); 
    return mergedOptions; 
    } 

    private saveToken(res: Response): void { 
    const token = res.headers.get(JWT_RESPONSE_HEADER); 
    if (token) localStorage.setItem(JWT_RESPONSE_HEADER, token); 
    } 
} 

服務,並將其納入你app.module.ts這樣

@NgModule({ 
    imports: [ 
     BrowserModule, 
     ContentModule, 
     routing, 
     HttpModule 
    ], 
    declarations: [ 
     AppComponent, 
     LoginComponent 
    ], 
    providers: [ 
     appRoutingProviders, 
     LoginService, 
     { 
      provide: Http, 
      useFactory: (backend: XHRBackend, defaultOptions: RequestOptions) => new AuthHttp(backend, defaultOptions), 
      deps: [XHRBackend, RequestOptions] 
     } 
    ], 
    bootstrap: [AppComponent] 
}) 
export class AppModule { 
} 
你沒有做出任何更改

你的其他服務女巫使用http

https://github.com/mtinner/CAS-FEE_Project2/blob/develop/src/frontend/components/common/authentication/auth-http.service.ts

https://github.com/mtinner/CAS-FEE_Project2/blob/ebab26fb8a8463cf9f65c3bc9e4d806d665bec7e/src/frontend/components/app.module.ts

+0

它適合你嗎?我有4.2.4版本的Angular和相同的解決方案,但不添加頭文件。 http.es5.js中的錯誤(Http.prototype.get函數)。看起來它與https://github.com/angular/angular/issues/19260有關 –

1
從角的4.3版本,你可以使用 HttpInterceptor

也。來自官方文檔的更多信息在這裏HttpInterceptor

@Injectable() 
export class AuthInterceptor implements HttpInterceptor { 
constructor(public auth: AuthService) {} 

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { 
    request = request.clone({ 
    setHeaders: {Authorization: `Bearer ${this.auth.getToken()}`} 
    }); 

    return next.handle(request); 
    } 
}