Forbidden (403) CSRF verification failed. Request aborted. Even using the {% csrf_token %}
Theory
A couple of things are required to make the csrf protection work (check out the docs):
- Your browser has to accept cookies from your server
- Make sure you have '
django.middleware.csrf.CsrfViewMiddleware'
included as middleware in yoursettings.py
(alternatively use the decorator csrf_protect() on particular views you want to protect) - Make sure you pass on the csrf token from
django.core.context_processors.csrf
to the context manager.
When you load your page, have a look in the page source using your favorite browser. Don't open the template html file, open the url which point to the view containing the form. Look at where you placed the {% csrf_token %}
. If you see something like
<input type='hidden' name='csrfmiddlewaretoken' value="jdwjwjefjwdjqwølksqøwkop2j3ofje" />
you should be ok.
If you on the other hand see NOTPROVIDED
, something has gone wrong while creating the csrf token. By looking in the source code (context_processors.py
and csrf.py
), we can find out what:
-
csrf(request)
returns{'csrf_token': 'NOTPROVIDED'}
ifget_token(request)
returns None. -
get_token(request)
returnsrequest.META.get("CSRF_COOKIE", None)
.
I assume this means that it would return None
if the cookie isn't successfully created.
Fix
For you, this means that you should first replace
<form action="/accounts/auth/" method="post" {% csrf_token %}>
with
<form action="/accounts/auth/" method="post">
{% csrf_token %}
(...)
</form>
We'd like the csrf field to be inside <form>...</form>
, not inside <form>
. As the code is at the moment, it will be converted to
<form action="/accounts/auth/" method="post" <input type='hidden' name='csrfmiddlewaretoken' value='randomchars' />>
and we would rather like
<form action="/accounts/auth/" method="post">
<input type='hidden' name='csrfmiddlewaretoken' value='randomchars' />
After that - have a look at the source code, and see if you can find the csrf field. If you can see it, everything should work in theory.
You can also check that the csrf cookie has been set in your browser, e.g. in Chrome, right-click the web page, and select Insepect Element
. Select the Resources
tab, and click on cookies. You should find a cookie name csrftoken
there.
If you still have problems, double-check the middleware tuple in your settings.py
and double-check that your browser accept cookier from your server as described above.
Clear your browser cache and try again. Maybe it is using the CSRF token saved in cached cookie.
With Addition of above answer, Try Adding following lines in the views
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def somathing():
return something