web-dev-qa-db-fra.com

Angular 6 set withCredentials à true avec chaque appel HttpClient

Si vous souhaitez que les informations d'identification (jeton d'authentification de cookie) puissent être transmises via un appel, vous devez ajouter { withCredentials: true } dans votre appel httpclient. Quelque chose comme ça:

import { HttpClient  } from '@angular/common/http';
...
constructor(private httpclient: HttpClient) { }

this.httpclient.get(url, { withCredentials: true })

Je voudrais juste savoir s'il existe un moyen de prédéfinir { withCredentials: true } à chaque appel. Je ne veux pas avoir à ajouter { withCredentials: true } chaque fois que je fais un appel.

Voici une question connexe, mais je ne sais pas si cela fonctionne avec HttpClient?

4
Freddy Bonda

Créez un HttpInterceptor

@Injectable()
export class CustomInterceptor implements HttpInterceptor { 

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

        request = request.clone({
            withCredentials: true
        });

        return next.handle(request);
    }
}

@NgModule({
  bootstrap: [AppComponent],
  imports: [...],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: CustomInterceptor ,
      multi: true
    }
  ]
})
export class AppModule {}
10
Sachila Ranawaka

Vous avez deux options ici -

  1. HttpInterceptor

auth.service.ts

Si vous écrivez une application standard qui nécessite une validation des informations d'identification maintenant ou plus tard, vous aurez besoin de AuthService. Cependant, vous pouvez ignorer dès maintenant si vous le souhaitez.

// src/app/auth/auth.service.ts
import { Injectable } from '@angular/core';
import decode from 'jwt-decode';
@Injectable()
export class AuthService {
  public getToken(): string {
    return localStorage.getItem('token');
  }
  public isAuthenticated(): boolean {
    // get the token
    const token = this.getToken();
    // return a boolean reflecting 
    // whether or not the token is expired
    return tokenNotExpired(null, token);
  }
}

app.module.ts

Fournir HTTP_INTERCEPTORS qui interceptera toute demande de votre part.

   // src/app/app.module.ts
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { TokenInterceptor } from './../auth/token.interceptor';
@NgModule({
  bootstrap: [AppComponent],
  imports: [...],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: TokenInterceptor,
      multi: true
    }
  ]
})
export class AppModule {}

token.interceptor.ts

Il s'agit d'Interceptor via lequel chaque requête HTTP passera.

// src/app/auth/token.interceptor.ts
import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';
import { AuthService } from './auth/auth.service';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class TokenInterceptor 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);
  }
}
  1. Remplacer le HttpClient standard

app.module.ts

    @NgModule({
        providers: [ // expose our Services and Providers into Angular's dependency injection
            {provide: HttpClient, useClass: ExtendedHttpService},
        ]
    })
    export class AppModule {
}

extended-http.service.ts

import {Injectable, Injector} from '@angular/core';
import {Request, XHRBackend, RequestOptions, Response, Http, RequestOptionsArgs, Headers} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {Router} from '@angular/router';
import {AuthService} from './auth.service';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

@Injectable()
export class ExtendedHttpService extends HttpClient {
    private router: Router;
    private authService: AuthService;

    constructor(backend: XHRBackend, defaultOptions: RequestOptions, private injector: Injector) {
        super(backend, defaultOptions);

    }

    request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {

        if (typeof url === 'string') {
            if (!options) {
                options = {headers: new Headers()};
            }
            this.setHeaders(options);
        } else {
            this.setHeaders(url);
        }
        //console.log("url: " , url , ", Options:" , options);
        return super.request(url, options).catch(this.catchErrors());
    }

    private catchErrors() {

        return (res: Response) => {
            if (this.router == null) {
                this.router = this.injector.get(Router);
            }
            if (res.status === 401 || res.status === 403) {
                //handle authorization errors
                //in this example I am navigating to login.
                console.log("Error_Token_Expired: redirecting to login.");
                this.authService.logout();
            }
            return Observable.throw(res);
        };
    }

    private setHeaders(objectToSetHeadersTo: Request | RequestOptionsArgs) {

        if (this.authService == null) {
            this.authService = this.injector.get(AuthService);
        }
        //add whatever header that you need to every request
        //in this example I could set the header token by using authService that I've created
        objectToSetHeadersTo.headers.set('Authorization', this.authService.getAuthToken());
    }
}
1
Sunil Singh