Tony Li
Tony Li

Reputation: 147

Django rejects Requests' CSRF Token

I'm writing an Ajax post with python's Request's library to a django backend

Code:

import requests
import json
import sys

URL = 'http://localhost:8000/'

client = requests.session()

client.get(URL)

csrftoken = client.cookies['csrftoken']


data = { 'file': "print \"It works!\"", 'fileName' : "JSONtest", 'fileExt':".py",'eDays':'99','eHours':'1', 'eMinutes':'1' }
headers = {'Content-type': 'application/json',  "X-CSRFToken":csrftoken}
r = requests.post(URL+"au", data=json.dumps(data), headers=headers)

Django gives me a 403 error stating that the CSRF token isn't set even though the request.META from csrf_failure() shows it is set. Is there something I'm missing or a stupid mistake I'm not catching?

Upvotes: 1

Views: 4385

Answers (2)

Tony Li
Tony Li

Reputation: 147

I asked my friend and he figured out the problem, basically you have to send the cookies that django gives you every time you do a request.

corrected:

cookies = dict(client.cookies)
r = requests.post(URL+"au", data=json.dumps(data), headers=headers,cookies=cookies)

Upvotes: 3

fasouto
fasouto

Reputation: 4511

You need to pass the referer to the headers, from the django docs:

In addition, for HTTPS requests, strict referer checking is done by CsrfViewMiddleware. This is necessary to address a Man-In-The-Middle attack that is possible under HTTPS when using a session independent nonce, due to the fact that HTTP ‘Set-Cookie’ headers are (unfortunately) accepted by clients that are talking to a site under HTTPS. (Referer checking is not done for HTTP requests because the presence of the Referer header is not reliable enough under HTTP.)

so change this:

headers = {'Content-type': 'application/json',  "X-CSRFToken":csrftoken, "Referer": URL}

Upvotes: 0

Related Questions