Beginner at Django here, I've been trying to fix this for a long time now.
I do have 'django.middleware.csrf.CsrfViewMiddleware' in my middleware classes and I do have the token in my post form.
Heres my code, what am I doing wrong?
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from chartsey.authentication.forms import RegistrationForm
from django.template import RequestContext
from django.core.context_processors import csrf
def register(request):
if request.method == 'POST':
c = RequestContext(request.POST, {})
form = RegistrationForm(c)
if form.is_valid():
new_user = form.save()
return HttpResponseRedirect("/")
else:
form = RegistrationForm()
return render_to_response("register.html", {'form': form, }, )
Here's my Template:
{% block content %}
<h1>Register</h1>
<form action="" method="POST"> {% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
{% endblock %}
Update: This answer is from 2011. CSRF is easy today.
These days you should be using the render shortcut function return render(request, 'template.html') which uses RequestContext automatically so the advice below is outdated by 8 years.
Use render https://docs.djangoproject.com/en/2.2/topics/http/shortcuts/
Add CSRF middleware https://docs.djangoproject.com/en/2.2/ref/csrf/
Use the {% csrf_token %} template tag
Confirm you see the CSRF token value being generated, AND submitted in your form request
Original Response
My guess is that you have the tag in the template but it's not rendering anything (or did you mean you confirmed in the actual HTML that a CSRF token is being generated?)
Either use RequestContext instead of a dictionary
render_to_response("foo.html", RequestContext(request, {}))
Or make sure you have django.core.context_processors.csrf in your CONTEXT_PROCESSORS setting.
https://docs.djangoproject.com/en/dev/ref/contrib/csrf/
Or add the token to your context manually
Just add this to your views
return render_to_response("register.html", {'form': form, }, context_instance = RequestContext(request))
It will work!!
Try using render instead of render_to_response:
from django.shortcuts import render
render(request, "foo.html", {})
Django - what is the difference between render(), render_to_response() and direct_to_template()?
As stated in the link above it was introduced in Django 1.3 and automatically uses RequestContext
for Django version 3.0 add the below annotation
#csrf_protect
def yourfunc(request):
return render(request, '../your.html', None)
And don't forget add the below tag in your field
<form action="add/" method="post">
{% csrf_token %}
...
</form>
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
The addition of RequestContext is the key when using render_to_response as mentioned by #Yuji 'Tomita' Tomita and #Njogu Mbau. However, what initially threw me off when I was struggling with this problem was that I had to add RequestContext to both the function in views.py that initially loads the template and to the function in views.py that handles the submission from the template.
Also, just for reference, here are some other links that discuss this same problem
Django - CSRF token missing or incorrect
Django 403 CSRF token missing or incorrect
Django --CSRF token missing or incorrect
Django CSRF Cookie Not Set *
Also got this error randomly on some pages after I installed django-livereload-server. Uninstalling django-livereload-server did the trick.
I had this issue too, but honestly, I hit refresh on my browser a few minutes later without changing anything and it worked that time. I had this message in my command line as so it might provide a clue as to what was causing the issue:
Not Found: /css/reset/reset.css
[03/Jul/2020 20:52:13] "GET /css/reset/reset.css HTTP/......
DJANGO/AJAX WORKFLOW FULL METHOD IS HERE :)
const url = "{% url 'YOUR_URL_NAME' pk=12345 %}".replace(/12345/, id.toString());
$.ajax({
type: 'POST',
url: url,
data: {'id':id, "csrfmiddlewaretoken": '{{csrf_token}}'},
beforeSend: function() { $('#response').text('Please wait ...'); },
success: function (response) {
console.log(response)
},
error: function (response) {
console.log(response)
}
})
Hope It Will Work !!!
What worked for me was commenting out the below line from my settings.py
'django.middleware.csrf.CsrfViewMiddleware'
Related
I’m using REST Easy in Firefox to make a POST request to a simple form in Django, but it’s giving me a 403 error “2295 CSRF token missing or incorrect”.
This is my views.py (since I’m using the net behind a proxy):
from django.shortcuts import render
import urllib2
def home(request):
if request.method == 'POST':
post = request.POST
if 'passkey' in post:
if post['passkey'] == '123':
proxy = urllib2.ProxyHandler({'http': 'http://070.13095070:pujakumari123#10.1.1.19:80'})
auth = urllib2.HTTPBasicAuthHandler()
opener = urllib2.build_opener(proxy, auth, urllib2.HTTPHandler)
urllib2.install_opener(opener)
j = urllib2.urlopen(post['url'])
j_obj = json.load(j)
return HttpResponse(j_obj)
else:
return render(request, 'packyourbag/home_page.html')
and my template file:
<html>
<body>
<form id="form" method="post">
{% csrf_token %}
url:<input type="text" name="url"/>
Pass Key:<input type="text" name="passkey"/>
<button type="submit" name="url_post">
Post
</button>
</form>
</body>
</html>
I’m passing a URL and passkey, and I don't know how to pass a CSRF token (I don’t even know if I have to pass this or not).
You can disable the CSRF token requirement by putting #csrf_exempt before your view:
First import the decorator at the top of your views.py:
from django.views.decorators.csrf import csrf_exempt
Then decorate your view like:
#csrf_exempt
def home(request):
Warning: This will make your view vulnerable to cross site request forgery attacks. See https://docs.djangoproject.com/en/dev/ref/csrf/ for details.
It is because you aren't passing the CSRF Token through with rest-easy. You can either do as #Selcuk suggested and wrap your view function with #csrf_exempt while testing, or you can find the CSRF Token and POST that with rest-easy
I have been trying to set up a test version of a captcha form using the Django CMS, Mezzanine. It displays the captcha, but when I submit the form I get the error:
Forbidden (403)
CSRF verification failed. Request aborted.
Help
Reason given for failure:
CSRF token missing or incorrect.
In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:
Your browser is accepting cookies.
The view function uses RequestContext for the template, instead of Context.
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
You're seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.
You can customize this page using the CSRF_FAILURE_VIEW setting.
The behavior is the same with Firefox and Chrome (with or without incognito). I am using Python 3.4, Django 1.6.7, and Mezzanine 3.1.0. I have tried to fix the problem in several ways:
1) My html template:
<body>
<h3>Captcha</h3>
<form method="POST">
{% csrf_token %}
<input name="item_text" id="id_new_item" placeholder="Enter item">
<br>
{{ form.captcha }}
<input type="submit" value="Submit">
</form>
</body>
2) In my settings.py file:
TEMPLATE_CONTEXT_PROCESSORS = (
...
"django.core.context_processors.csrf",
)
MIDDLEWARE_CLASSES = (
...
"django.middleware.csrf.CsrfViewMiddleware",
)
3) In my captcha_test.views.py:
from django.views.decorators.csrf import csrf_protect
from django.shortcuts import render_to_response
from django.http import HttpResponse
from captcha_test.forms import CaptchaTestForm
#csrf_protect
def captcha_page(request):
if request.POST:
form = CaptchaTestForm(request.post)
if form.is_valid():
human = True
return HttpResponseRedirect('/')
else:
form = CaptchaTestForm()
return render_to_response('captcha.html', locals())
My forms.py file, if this helps at all:
from django import forms
from captcha.fields import CaptchaField
class CaptchaTestForm(forms.Form):
item_text = forms.CharField()
captcha = CaptchaField()
Any insights? Thanks for your help!
You must ensure that:
The view function uses RequestContext for the template, instead of Context.
But you use:
return render_to_response('captcha.html', locals())
And, from the documentation to render_to_response:
By default, the template will be rendered with a Context instance (filled with values from dictionary). If you need to use context processors, render the template with a RequestContext instance instead.
So adding context_instance=RequestContext(request) should solve the problem.
So I am getting Forbidden (403) CSRF verification failed. Request aborted. Reason given for failure: CSRF token missing or incorrect.
I have the 'django.middleware.csrf.CsrfViewMiddleware', in my middleware_classes.
Here is my template
<form name="input" action="/login/" method="Post"> {% csrf_token %}
<input type="submit" value="Submit"></form>
Here is my view
from django.shortcuts import render_to_response
from django.core.context_processors import csrf
from django.template import RequestContext
def login(request):
csrfContext = RequestContext(request)
return render_to_response('foo.html', csrfContext)
Well I am new to Django and most web development, but I cannot seem to find the problem here. Any help would be much appreciated!
Also i have tried the method in the django documentation
c = {}
c.update(csrf(request))
# ... view code here
return render_to_response("a_template.html", c)
I had the same problem with you and i found this code that solve my problem.
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render
from django.contrib import auth
#in accounts.forms i've placed my login form with two fields, username and password
from accounts.forms import LoginForm
#csrf_exempt
def login(request):
if request.method == "POST":
form = LoginForm(request.POST)
if form.is_valid():
user = auth.authenticate(
username=form.cleaned_data["username"],
password=form.cleaned_data["password"])
auth.login(request, user)
return HttpResponseRedirect("/")
else:
form = LoginForm()
return render(request, 'accounts/login.html', {'form':form})
Try adding the #csrf_protect decorator just before your login function.
from django.views.decorators.csrf import csrf_protect
#csrf_protect
def login(request):
csrfContext = RequestContext(request)
return render_to_response('foo.html', csrfContext)
If the form is not in foo.html then you need to add the #csrf_protect method to the view function that is generating it.
Just add this line .
$.ajaxSetup({
data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});
You should do the following:
def login(request):
context = {}
request_context = RequestContext(request)
return render_to_response('foo.html', context,
request_context=request_context)
Here are official docs for render_to_response.
go urls and add the .as_view() next to the view metho/class
ex.
ObtainAuthTokenView.as_view()
While disabling the CSRF tokens and manually getting the CSRF token value would still have worked. But, in my case the syntax was not properly structured as in html we don't worry about our script design but I think when using jinja i.e. Our templating language it matter's and yes that's how I solved my problem.
Just add this in your HTML:
{% csrf_token %}
I try to build a very simple website where one can add data into sqlite3 database. I have a POST form with two text input.
index.html:
{% if top_list %}
<ul>
<b><pre>Name Total steps</pre></b>
{% for t in top_list %}
<pre>{{t.name}} {{t.total_steps}}</pre>
{% endfor %}
</ul>
{% else %}
<p>No data available.</p>
{% endif %}
<br>
<form action="/steps_count/" method="post">
{% csrf_token %}
Name: <input type="text" name="Name" /><br />
Steps: <input type="text" name="Steps" /><br />
<input type="submit" value="Add" />
</form>
forms.py:
from django import forms
from steps_count.models import Top_List
class Top_List_Form(forms.ModelForm):
class Meta:
model=Top_List
views.py:
# Create your views here.
from django.template import Context, loader
from django.http import HttpResponse
from steps_count.models import Top_List
from steps_count.forms import Top_List_Form
from django.template import RequestContext
from django.shortcuts import get_object_or_404, render_to_response
def index(request):
if request.method == 'POST':
#form = Top_List_Form(request.POST)
print "Do something"
else:
top_list = Top_List.objects.all().order_by('total_steps').reverse()
t = loader.get_template('steps_count/index.html')
c = Context({'top_list': top_list,})
#output = ''.join([(t.name+'\t'+str(t.total_steps)+'\n') for t in top_list])
return HttpResponse(t.render(c))
However, when I click the "submit" button, I get the 403 error:
CSRF verification failed. Request aborted.
I have included {% csrf_token %} in index.html. However, if it is a RequestContext problem, I really have NO idea on where and how to use it. I want everything to happen on the same page (index.html).
You may have missed adding the following to your form:
{% csrf_token %}
Use the render shortcut which adds RequestContext automatically.
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render
from steps_count.models import Top_List
from steps_count.forms import Top_List_Form
def index(request):
if request.method == 'POST':
#form = Top_List_Form(request.POST)
return HttpResponse("Do something") # methods must return HttpResponse
else:
top_list = Top_List.objects.all().order_by('total_steps').reverse()
#output = ''.join([(t.name+'\t'+str(t.total_steps)+'\n') for t in top_list])
return render(request,'steps_count/index.html',{'top_list': top_list})
When you found this type of message , it means CSRF token missing or incorrect. So you have two choices.
For POST forms, you need to ensure:
Your browser is accepting cookies.
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
The other simple way is just commented one line (NOT RECOMMENDED)('django.middleware.csrf.CsrfViewMiddleware') in MIDDLEWARE_CLASSES from setting tab.
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
add it to the setting file
CSRF_TRUSTED_ORIGINS = [
'https://appname.herokuapp.com'
]
One more nicest alternative way to fix this is to use '#csrf_exempt' annotation.
With Django 3.1.1 you could just use #csrf_exempt on your method.
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def index(request):
and you don't need to specify {% csrf_token %} in your html.
happy learning..
A common mistake here is using render_to_response (this is commonly used in older tutorials), which doesn't automatically include RequestContext. Render does automatically include it.
Learned this when creating a new app while following a tutorial and CSRF wasn't working for pages in the new app.
In your HTML header, add
<meta name="csrf_token" content="{{ csrf_token }}">
Then in your JS/angular config:
app.config(function($httpProvider){
$httpProvider.defaults.headers.post['X-CSRFToken'] = $('meta[name=csrf_token]').attr('content');
}
if you are using DRF you will need to add #api_view(['POST'])
function yourFunctionName(data_1,data_2){
context = {}
context['id'] = data_1
context['Valid'] = data_2
$.ajax({
beforeSend:function(xhr, settings) {
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
if (settings.url == "your-url")
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
},
url: "your-url",
type: "POST",
data: JSON.stringify(context),
dataType: 'json',
contentType: 'application/json'
}).done(function( data ) {
});
If you put {%csrf_token%} and still you have the same issue, please try to change your angular version. This worked for me. Initially I faced this issue while using angular 1.4.x version. After I degraded it into angular 1.2.8, my problem was fixed. Don't forget to add angular-cookies.js and put this on your js file.
If you using post request.
app.run(function($http, $cookies) {
console.log($cookies.csrftoken);
$http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;
});
USE decorator:
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def method_name():
# body
Ensure that your browser is accepting cookies. I faced the same issues.
1) {% csrf_token %} is not in template
-- or --
2) {% csrf_token %} is outside of html-form
If the user anonymous or not, how can i check that in base.html?
Which is correct?
{% if request.user.is_authenticated %}
Or
{% if user.is_authenticated %}
How can i pass the variable request.user in base.html?
Try using the Request context:
from django.template import RequestContext
# in a view
return render_to_response('base.html', context_instance = RequestContext(request))
Make sure you take a look at these context processors: https://docs.djangoproject.com/en/dev/ref/templates/api/#django-contrib-auth-context-processors-auth
And then you should be able to access user in your templates
You can use the django shortcut render to always render a template that is automatically passed a RequestContent:
https://docs.djangoproject.com/en/dev/topics/http/shortcuts/#module-django.shortcuts