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
):
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?
Le problème, encore une fois, tient à la piètre documentation d'Angular.
En fait, Angular ajoutera l'en-tête X-XSRF-TOKEN
uniquement si le cookie XSRF-TOKEN
a été généré côté serveur avec les options suivantes:
/
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
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
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;
}