10👍
Victor K’s answer is perfectly valid however as of angular 2.0.0-rc.2, a preferred approach would be to use CookieXSRFStrategy as below,
bootstrap(AngularApp, [
HTTP_PROVIDERS,
provide(XSRFStrategy, {useValue: new CookieXSRFStrategy('csrftoken', 'X-CSRFToken')})
]);
20👍
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 {
},
13👍
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})
]);
- How does django-nose differ from the default Django test-runner
- What does it mean for an object to be unscriptable?
4👍
For later versions of angular you cannot call functions in decorators. You have to use a factory provider:
export function xsrfFactory() {
return new CookieXSRFStrategy('_csrf', 'XSRF-TOKEN');
}
And then use the factory:
providers: [
{
provide: XSRFStrategy,
useFactory : xsrfFactory
}],
Otherwise the compiler will tell you off.
What I have also seen is that ng build –watch will not report this error until you kick it off again.
- How does use_for_related_fields work in Django?
- Django database synchronization for an offline usage
- How to emit SocketIO event on the serverside
- You cannot add messages without installing django.contrib.messages.middleware.MessageMiddleware
- Converting a django ValuesQuerySet to a json object
3👍
I struggled with this for a few days. The advice in this article is good, but as of August, 2017 is deprecated (https://github.com/angular/angular/pull/18906). The angular2 recommended approach is simple, but has a caveat.
The recommend approach is to use HttpClientXsrfModule and to configure it to recognize django’s default csrf protection. According to the django docs, django will send the cookie csrftoken
and expect the client to return the header X-CSRFToken
. In angular2, add the following to your app.module.ts
import { HttpClientModule, HttpClientXsrfModule } from '@angular/common/http';
@NgModule({
imports: [
HttpClientModule,
HttpClientXsrfModule.withOptions({
cookieName: 'csrftoken',
headerName: 'X-CSRFToken',
})
], ...
The caveat is that angular2’s XSRF Protection only applies to mutating requests:
By default, an interceptor sends this cookie [header] on all mutating requests
(POST, etc.) to relative URLs but not on GET/HEAD requests or on
requests with an absolute URL.
If you need to support an API that performs mutation on GET/HEAD, you will need to create your own custom interceptor. You can find an example and a discussion of the issue here.
- How to make follower-following system with django model
- How can I schedule a Task to execute at a specific time using celery?
2👍
Victor K had the solution, I’ll just add this comment here as to what I did:
I created the component “ExRequestOptions” as Victor K said, but I also added a method “appendHeaders” to that component:
appendHeaders(headername: string, headervalue: string) {
this.headers.append(headername, headervalue);
}
Then I had this in my main.ts:
import {bootstrap} from 'angular2/platform/browser'
import {AppComponent} from './app.component'
import {HTTP_PROVIDERS, RequestOptions} from 'angular2/http';
import 'rxjs/Rx';
import {ExRequestOptions} from './transportBoxes/exRequestOptions';
import {provide} from 'angular2/core';
bootstrap(AppComponent,[ HTTP_PROVIDERS,
provide(RequestOptions, {useClass: ExRequestOptions})]);
I’m not sure the bootstrapping had any effect, so i also did this where
I would post data:
let options = new ExRequestOptions();
options.appendHeaders('Content-Type', 'application/json');
return this.http.post('.....URL', JSON.stringify(registration),
options)
- TypeError: create_superuser() missing 1 required positional argument: 'profile_picture'
- How to create custom groups in django from group
- Django unable to find MySQLdb python module
1👍
Currently, I solve anything with custom headers using a wrapper service around the Http Service. You can add whatever header manually and inject additional services for storing/retrieving values. This strategy also works for JWTs, for example. Have a look at the code below, I hope it helps.
import {Injectable} from '@angular/core';
import {Http, Headers, RequestOptions} from '@angular/http';
@Injectable()
export class HttpService {
constructor(private http: Http) {
}
private get xsrfToken() {
// todo: some logic to retrieve the cookie here. we're in a service, so you can inject anything you'd like for this
return '';
}
get(url) {
return this.http.get(url, this.getRequestOptions())
.map(result => result.json())
.catch(error => error.json());
}
post(url, payload) {
return this.http.post(url, payload, this.getRequestOptions())
.map(result => result.json())
.catch(error => error.json());
}
private getRequestOptions() {
const headers = new Headers({'Content-Type': 'application/json', 'X-XSRF-TOKEN': this.xsrfToken});
return new RequestOptions({headers: headers});
}
}