web-dev-qa-db-fra.com

Angular 6 n'ajoute pas l'en-tête X-XSRF-TOKEN à la requête http.

J'ai lu la documentation et toutes les questions connexes sur SO, mais le mécanisme XSRF d'Angular ne fonctionne toujours pas pour moi: je ne peux en aucun cas faire une demande POST avec X-XSRF-TOKEN. en-tête ajouté automatiquement.

J'ai une application Angular 6 avec un formulaire de connexion. 

Cela fait partie d'un site Web Symfony (PHP 7.1), et la page d'application Angular, lorsqu'elle est servie par Symfony, envoie le cookie correct (XSRF-TOKEN):

 enter image description here

Mon app.module.ts comprend les bons modules:

// other imports...
import {HttpClientModule, HttpClientXsrfModule} from "@angular/common/http";

// ...
@NgModule({
  declarations: [
    // ...
  ],
  imports: [
    NgbModule.forRoot(),
    BrowserModule,
    // ...
    HttpClientModule,
    HttpClientXsrfModule.withOptions({
      cookieName: 'XSRF-TOKEN',
      headerName: 'X-CSRF-TOKEN'
    }),
    // other imports
  ],
  providers: [],
  entryComponents: [WarningDialog],
  bootstrap: [AppComponent]
})
export class AppModule {
}

Ensuite, dans la méthode d'un service, je fais la requête http suivante (this.http est une instance de HttpClient):

this.http
    .post<any>('api/login', {'_username': username, '_pass': password})
    .subscribe(/* handler here */);

La demande de publication n'envoie jamais l'en-tête X-XSRF-TOKEN. Pourquoi?

6
Paolo Stefan

Le problème, encore une fois, tient à la piètre documentation d'Angular.

En fait, Angular ajoutera l'en-tête X-XSRF-TOKENuniquement si le cookie XSRF-TOKEN a été généré côté serveur avec les options suivantes:

  • Chemin = /
  • httpOnly = false (c'est très important, et complètement undocumented)

En outre, l'application angulaire et l'URL appelée doivent résider sur le même serveur.

Référence: ce numéro de Github Angulaire

11
Paolo Stefan

Assurez-vous que votre serveur autorise les en-têtes X-CSRF-Token lorsque browser demande la méthode OPTIONS .

Exemple:

Access-Control-Allow-Headers: X-CSRF-Token, Content-Type

Référence: MDN Docs

1
Ritwick Dey

Un peu en dehors du sujet, mais pour les autres qui viennent ici, j'ai résolu ce problème à l'arrière-plan en procédant comme suit (pour spring-boot)

     /**
     * CORS config - used by cors() in configure() DO NOT CHANGE the METDHO NAME
     * 
     * @return
     */
    @Bean()
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Lists.newArrayList("http://localhost:4200"));
        configuration.setAllowedMethods(Lists.newArrayList("GET", "POST", "OPTIONS"));
        configuration.setAllowCredentials(true);
        configuration.setAllowedHeaders(Lists.newArrayList("x-xsrf-token", "XSRF-TOKEN"));
        configuration.setMaxAge(10l);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
1
Anand Rockzz