Skip to content Skip to sidebar Skip to footer

Python-requests And Django - Csrf Verification Failed. Request Aborted

I have a django server to upload files and when I use a browser, I can upload the file without problems. But if I use the python-requests commands, it tells me CSRF verification fa

Solution 1:

It's actually all working fine, you just have to understand how csrf works. When you load the page in your browser, you get a csrf token inside {% csrf_token %}, So when you send the data to the server, you also send along the csrf token.

When you use requests, you're getting the cookie in the 'get' part, but you're not sending it along with your 'post'. without it, you're just sending a post request with no token at all, which means a CSRF verification error. To solve it, try this code:

file = {"docfile": open(fullfilename, "rb")}
s = requests.Session()
r1 = s.get(dhost)
csrf_token = r1.cookies['csrftoken']
r2 = s.post(dhost, files=file, data={'csrfmiddlewaretoken': csrf_token}, headers=dict(Referer=dhost))

If this is just for your own usage, you can disable csrf on that view using csrf_exampt:

@csrf_exemptdefmy_view(request):
   ...whateva...

But note that this isn't a recommended solution if you plan to launch your server and open it to the public

Solution 2:

If I use the python-requests commands, it tells me CSRF verification failed. But if I look in the header I sent, I have the cookie set:

'Content-Length': u'84169', 
  'Accept-Encoding': 'gzip, deflate, compress', 
  'Accept': '/', 
  'User-Agent': 'python-requests/2.0.1 CPython/2.7.3 Linux/3.6.11+',
  'Cookie': 'csrftoken=GOOIsG89i5oMCJO6594algTXooxoUeoL',
  'Content-Type': 'multipart/form-data; boundary=86ada00b4f6c41d5997293cce7a53b6b

You have to send two things back to the server:

1) The csrftoken cookie.

2) The following form name/value pair:

"csrfmiddlewaretoken" = "csrf token here"

A requests session will take care of returning the cookie for you, but you have to add the form name/value pair:

sess = requests.Session()
r = sess.get(get_url)
my_csrf_token = r.cookies['csrftoken']

withopen('myfile.txt') as f:
    r = sess.post(
        post_url,
        data = {
            "csrfmiddlewaretoken": my_csrf_token,
        },
        files = {"myfile": f}

)

print r.status_code
print r.text

When your django html template contains a csrf tag:

<form name="myMessage" 
      method="post"class="signin" 
      action="/myapp/process_form/"
      enctype="multipart/form-data">

{% csrf_token %}

the csrf tag is replaced by a hidden form field:

<inputtype="hidden" 
       value="RTpun6OhlRehRRa2nAIcTtFJk5WuWsLg" 
       name="csrfmiddlewaretoken">

The hidden form field sends an additional name/value pair to the server along with all the other name/value pairs that the form creates. The name is "csrfmiddlewaretoken" and the value is the csrf token. django checks for the cookie as well as the name/value pair in the form data.

By the way, in order to get a csrf token for testing purposes, you can make a get request to a view that looks like this:

defmyview(request):
    from django.middleware.csrf import get_token
    get_token(request)  #This causes django to set the csrftoken cookie in the responsereturn HttpResponse('server received GET request')

Solution 3:

It depends what you're trying to do.

If you do not need CSRF verification you can use the csrf_exempt decorator.

Or you can create a new csrf_exempt view for only accessing through python-requests.

Post a Comment for "Python-requests And Django - Csrf Verification Failed. Request Aborted"