2016-02-09 19 views
7

Chcę sprawdzić wszystkie moje odpowiedzi http z jednego miejsca. Na przykład stan uwierzytelnienia. Jeśli odpowiedź mówi, że użytkownik nie jest już uwierzytelniony, chcę przekierować lub coś innego. Czy istnieje jakiś sposób, aby to zrobić.Jak napisać przechwytywacz http dla AngularJS 2?

+1

Powinieneś rzucić okiem na ten dokument https://github.com/angular/http/issues/80. Angular2 Http przechwytywacze i transformatory są obecnie mocno dyskutowane. Jeśli potrzebujesz przekierować nieuwierzytelnionego użytkownika, poleciłbym tę stronę serwera (z wyjątkiem SPA). – Antoine

Odpowiedz

5

Zaczynamy

Tworzenie obsługa jak tego

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); 
    } 
} 

I umieścić go w ty app.module.ts jak ten

@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 { 
} 

nie trzeba wprowadzać żadnych zmian w Twoja inna usługa korzysta z 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

Czy to działa? Mam wersję 4.2.4 Angulara i tego samego rozwiązania, ale nagłówek nie został dodany. Błąd w http.es5.js (funkcja Http.prototype.get). Wygląda na to, że jest to powiązane z https://github.com/angular/angular/issues/19260 –

1

Również od wersji 4.3 kątowych można wykorzystać HttpInterceptor. Więcej informacji z oficjalnej dokumentacji znajduje się tutaj 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); 
    } 
} 
Powiązane problemy