问题
I'm frequently testing my application using curl
and in the past I've had to simply wrap my views with csrf_exempt
. I really don't want to do this, as I have a nasty feeling that I'll forget to do this in deployment and enjoy a lifetime of CSRF hell.
Is there a way for me to request a CSRF token using Django's shell commands? I'd like to get a token I could send with my curl
requests to test things safely.
回答1:
Make an initial GET request to the form URL in order to fill the cookie jar:
$ curl http://example.com/some-form/ -o /dev/null -c cookies.txt -s
Get the value of the csrftoken
cookie:
$ grep csrftoken cookies.txt | cut -f 7
YQkfXZCKtPP0hC30NmH10jSWuf6yJA5E
When issuing a POST, just include a csrfmiddlewaretoken
field with this value (and use the same cookie jar).
I use the same trick to write end-to-end tests using the requests
library.
回答2:
you can do like this
from django.middleware.csrf import _get_new_csrf_key()
request.META["CSRF_COOKIE"] = _get_new_csrf_key()
回答3:
While working on an issue related to this, I wanted to test setting CSRF tokens for a bunch of endpoints that are accessible via AJAX. I came upon this thread and thought it might be worth it to add one other way to do it from the Django shell, which is what the original poster seemed to be asking about.
First of all, I am using the requests
library, so if you don't have it you have to do pip install requests
.
Ensure Token Exists
Next, if dealing only with Ajax endpoints, we need some way of retrieving a token, so the get method of your view must have the following decorator set, because as mentioned in the Django docs the token won't be set if you're generating forms dynamically. Here's a class-based-views example:
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import ensure_csrf_cookie
@method_decorator(ensure_csrf_cookie)
def get(self, request, *args, **kwargs):
return SomeJson...
DRF Post: Ensure csrf_protect
I am also using Django Rest Framework views, so I had to explicitly set csrf_protect
on my POST:
from django.views.decorators.csrf import csrf_protect
@method_decorator(ensure_csrf_cookie)
def post(self, request, *args, **kwargs):
return SomeJson...
Retrieve token from shell and POST it back
Finally, to get a token from the get
method and POST it back to the post
method, I did the following:
>>> resp = requests.get(url)
>>> cookies = resp.cookies
>>> token = cookies['csrftoken']
>>> data = {'content': True, 'we': None, 'are': False, 'posting': 0}
>>> data['csrfmiddlewaretoken'] = token
>>> resp2 = requests.post(url, data=data, cookies=cookies)
>>> resp2
<Response [200]>
来源:https://stackoverflow.com/questions/19827164/how-can-i-get-a-csrf-token-from-the-command-line