In Angular1 the problem can be solved by configuring $http-provider. Like:
app.config(function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
});
What is a good practice to do the same in Angular2?
In Angular2 to work with http requests we need to use class Http. Of course that's not a good practice to add CSRF-line to each call of post-function.
I guess in Angular2 I should create own class that inherits Angular2's Http class and redefine the post-function. Is it the right approach or is there a more elegant method?
CSRF protection works by checking for a secret in each POST request. This ensures that a malicious user cannot “replay” a form POST to your website and have another logged in user unwittingly submit that form. The malicious user would have to know the secret, which is user specific (using a cookie).
Django protects against CSRF attacks by generating a CSRF token in the server, send it to the client side, and mandating the client to send the token back in the request header. The server will then verify if the token from client is the same as the one generated previously; if not it will not authorise the request.
Now that Angular 2 is released the following seems to be the correct way of doing this, by using CookieXSRFStrategy
.
I've configured my application to have a core module but you can do the same in your main application module instead:
import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpModule, XSRFStrategy, CookieXSRFStrategy } from '@angular/http';
@NgModule({
imports: [
CommonModule,
HttpModule
],
declarations: [ ],
exports: [ ],
providers: [
{
provide: XSRFStrategy,
useValue: new CookieXSRFStrategy('csrftoken', 'X-CSRFToken')
}
]
})
export class CoreModule {
},
Solution for Angular2 is not as easy as for angular1. You need:
Pick out csrftoken
cookie value.
Add this value to request headers with name X-CSRFToken
.
I offer this snippet:
import {Injectable, provide} from 'angular2/core';
import {BaseRequestOptions, RequestOptions} from 'angular2/http'
@Injectable()
export class ExRequestOptions extends BaseRequestOptions {
constructor() {
super();
this.headers.append('X-CSRFToken', this.getCookie('csrftoken'));
}
getCookie(name) {
let value = "; " + document.cookie;
let parts = value.split("; " + name + "=");
if (parts.length == 2)
return parts.pop().split(";").shift();
}
}
export var app = bootstrap(EnviromentComponent, [
HTTP_PROVIDERS,
provide(RequestOptions, {useClass: ExRequestOptions})
]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With