Après avoir passé deux jours complets à chercher sur le Web et à lire des docs et des tonnes de questions en suspens concernant des personnes confrontées au même problème, je ne comprends toujours pas comment Angular 2 traite les cookies (x-Origin) et comment y accéder.
Le problème: Le serveur back-end envoie 2 cookies avec x-csrf-token & JSESSIONID à l'intérieur. Mon travail consiste à conserver le jeton csrf en mémoire (ng2) et à le renvoyer (uniquement) en tant que en-tête (sans cookie) avec chaque message envoyé au serveur dorsal.
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Access-Control-Allow-Origin: http://localhost:4200
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: Access-Control-Allow-Origin,Access-Control-Allow-Credentials
Set-Cookie: x-csrf-token=8555257a-396f-43ac-8587-c6d489e76026; Path=/app
Set-Cookie: JSESSIONID=73E38392C60370E38FBAF80143ECE212; Path=/app/; HttpOnly
Expires: Thu, 12 Apr 2018 07:49:02 GMT
Cache-Control: max-age=31536000
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 12 Apr 2017 07:49:02 GMT
Ma solution partielle: J'ai créé une classe RequesstOptions personnalisée qui étend BaseRequestOptions. Ajout d’en-têtes supplémentaires et définition du paramètre 'withCredentials'.
export class MyRequestOptions extends BaseRequestOptions {
headers: Headers = new Headers({
'Accept': 'application/json',
'Content-Type': 'application/json',
});
withCredentials = true;
}
Dans mon HttpService je fais le post et je me fais comme ça:
@Injectable()
export class HttpService {
constructor(
protected _http: Http,
protected requestOptions: RequestOptions
) { }
get(url): Observable<any> {
return this._http.get(url, this.requestOptions).map( res => res.json() );
}
post(url: string, object: any): Observable<any> {
return this._http.post(url, object, this.requestOptions).map( res => res.json() );
}
}
et dans mon app.module je fais la magie comme suit:
providers: [
{ provide: RequestOptions, useClass: DocumentumDefaultRequestOptions },
{ provide: XSRFStrategy, useFactory: xsrfFactory }
],
mon xsrfFactory
export function xsrfFactory() {
return new CookieXSRFStrategy('x-csrf-token', 'x-csrf-token');
}
Mon résultat partiel: À ce stade, Angular envoie un cookie à chaque requête (GET et POST sans discrimination) avec les attributs jsessionid et x-csrf-token, comme suit:
POST /app/business-objects/business-objects-type HTTP/1.1
Host: localhost:8040
Connection: keep-alive
Content-Length: 26
Pragma: no-cache
Cache-Control: no-cache
Authorization: Basic ZG1hZG1pbjphZG1pbg==
Origin: http://localhost:4200
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Content-Type: application/json
Accept: application/json
Referer: http://localhost:4200/page
Cookie: JSESSIONID=B874C9A170EFC12BEB0EDD4266896F2A; x-csrf-token=0717876e-f402-4a1c-a31a-2d60e48509d3
Mes questions d'un milliard de dollars:
CookieXSRFStrategy('x-csrf-token', 'x-csrf-token');
? Je n'aime pas la sensation de boîte noire/comprend la façon dont les docs l'ont expliqué. Puis-je y accéder pour des données?Avant d'envoyer une demande HTTP, CookieXSRFStrategy recherche un cookie appelé XSRF-TOKEN et définit un en-tête nommé X-XSRF-TOKEN avec la valeur de ce cookie.
Cela ne définit pas l'en-tête dans mon cas ... mais pourquoi?
En ce moment, j'envoie le cookie au serveur avec les identifiants sessionid et csrf, mais que envoie-t-il? L'indicateur CookieXSRFStrategy ou 'withCredentials'.
Merci de ne pas répondre avec un seul type de document comme "document.cookie". Les données sont inutiles sans leurs métadonnées
Angular a un support intégré pour XSRF voir ici: https://angular.io/guide/http#security-xsrf-protection
"Lors de l'exécution de requêtes HTTP, un intercepteur lit un jeton dans un cookie, par défaut, XSRF-TOKEN, et le définit comme un en-tête HTTP, X-XSRF-TOKEN"
Donc, si votre serveur définit un cookie nommé XSRF-TOKEN, alors il fonctionnera automatiquement! Rien à faire côté client . Si vous souhaitez nommer votre cookie/en-tête de quelque manière que ce soit, vous pouvez le faire. ainsi que:
imports: [
HttpClientModule,
HttpClientXsrfModule.withConfig({
cookieName: 'My-Xsrf-Cookie',
headerName: 'My-Xsrf-Header',
}),
]
ET si vous utilisez la sécurité de printemps, il prend en charge les conventions de dénomination angulaire afin que vous puissiez configurer ce côté serveur:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.authorizeRequests()
....