41 votes

Angular 4 - paramétrage de withCredentials à chaque requête - cors cookie

Mon client angulaire est séparé du backend et j'ai activé les cors sur le backend, tout fonctionne bien sauf le fait que mon authentification échoue car le cookie n'est pas ajouté aux requêtes.

Après avoir fait des recherches en ligne, j'ai trouvé que je devais mettre {withCredentials : true} sur chaque requête http. J'ai réussi à le faire sur une seule requête et ça marche, mais pas sur toutes les requêtes.

J'ai essayé d'utiliser BrowserXhr Comment envoyer "Cookie" dans l'en-tête de la demande pour toutes les demandes en Angular2 ? mais cela ne fonctionne pas et c'est également déprécié.

J'ai également essayé RequestOptions mais cela n'a pas fonctionné.

Que puis-je faire pour définir {withCredentials : true} sur chaque requête http ?

Édition ultérieure :

@Injectable()
export class ConfigInterceptor implements HttpInterceptor {

  constructor(private csrfService: CSRFService) {

  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let token = this.csrfService.getCSRF() as string;
    const credentialsReq = req.clone({withCredentials : true, setHeaders: { "X-XSRF-TOKEN": token } });
    return next.handle(credentialsReq);
  }
}

51voto

Venomy Points 1107

Vous pouvez utiliser un HttpInterceptor .

@Injectable()
export class CustomInterceptor implements HttpInterceptor {

    constructor() {
    }

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

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

        return next.handle(request);
    }
}

Ensuite, vous devez le fournir :

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

Source et explication complète

0voto

Jess Points 2039

Un autre moyen, peut-être plus simple, est de créer votre propre ApiService . Il utiliserait un système injecté HttpClient . Toutes les requêtes XHR utiliseraient le ApiService au lieu du HttpClient directement.

Voici un exemple de mise en œuvre :

https://github.com/gothinkster/angular-realworld-example-app/blob/63f5cd879b5e1519abfb8307727c37ff7b890d92/src/app/core/services/api.service.ts

Une partie du code que j'ai modifié :

@Injectable()
export class ApiService {

  private httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
    withCredentials: true // to allow cookies to go from "https://localhost:4567" to "http://localhost:5678"
  };

  constructor(
    private http: HttpClient
  ) { }

  private formatErrors(error: any) {
    return throwError(error.error);
  }

  get(path: string, params: HttpParams = new HttpParams()): Observable<any> {
    return this.http.get(`${environment.api_url}${path}`, { params })
      .pipe(catchError(this.formatErrors));
  }

  put(path: string, body: Object = {}): Observable<any> {
    return this.http.put(
      `${environment.api_url}${path}`,
      JSON.stringify(body),
      this.httpOptions
    ).pipe(catchError(this.formatErrors));
  }

  post(path: string, body: Object = {}): Observable<any> {
    return this.http.post(
      `${environment.api_url}${path}`,
      JSON.stringify(body),
      this.httpOptions
    ).pipe(catchError(this.formatErrors));
  }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X