mercredi 28 mai 2014

python - vérification de la CSRF a échoué. Demande abandonnée - desservant un modèle Django comme Server-Side Include - Stack Overflow


I've been at this for a few hours. I'm relatively new with Django and I need help in a setup that doesn't seem all that common.


I'm serving my website with Nginx and UWSGI where most of the pages are static and not served using Django. The only reason I'm using Django is for implementing a form. Therefore, I decided to SSI just the form template itself into a <div> within an existing HTML outside of the Django server. The form actually works great when DEBUG = True, but when False the form would render but throws an error when trying to submit. The error is "Forbidden (403) CSRF verification failed. Request aborted. Reason given for failure: CSRF cookie not set." Now the solutions I've found only assume that the whole website is served by Django. However, for me, only a snippet of Django template is served using Nginx's SSI. I'm wondering what the issue is and if the community can help me. Thanks in advance!


HTML outside of Django:  
<div id="formContainer"><!--#include virtual="/webform/contact/" --></div>



#Django view
def contact(request):
if request.method == 'POST': # If the form has been submitted...
form = ContactForm(request.POST) # A form bound to the POST data

if form.is_valid(): #All validation rules pass
# Process the data in form.cleaned_data
firstName = form.cleaned_data['firstName']
lastName = form.cleaned_data['lastName']
street = form.cleaned_data['street']
city = form.cleaned_data['city']
state = form.cleaned_data['state']
zipcode = form.cleaned_data['zipcode']
phone = form.cleaned_data['phone']
email = form.cleaned_data['email']
message = form.cleaned_data['message']

request.session['fname_ses'] = firstName
request.session['lname_ses'] = lastName
request.session['street_ses'] = street
request.session['city_ses'] = city
request.session['state_ses'] = state
request.session['zip_ses'] = zipcode
request.session['phone_ses'] = phone
request.session['email_ses'] = email
request.session['phone_ses'] = phone
request.session['email_ses'] = email
request.session['message_ses'] = message

subject = "A message for _____ from %s %s" %(firstName, lastName)
message_body = ("Here is the personal information provided by the client: \n"
" Full name: %s %s \n"
" Address: %s, %s, %s %s \n"
" Phone: %s \n"
" Email: %s \n \n"
"Message to you: \n \n%s"
%(firstName, lastName, street, city, state, zipcode, phone, email, message)
)
sender = "email1@example.com"
recipients = [
'email1@example.com',
'email2@example.com',
email3@example.com',
]

from django.core.mail import send_mail
send_mail(subject, message_body, sender,
recipients, fail_silently=False)

#Redirect after POST
#reverse() redirects straight to the view instead of the URL
#Use reverse() to prevent URL from appending to current address
return HttpResponseRedirect('webform/thanks_simple.html')
#return HttpResponseRedirect(reverse('webform:thanks'))
else:
form = ContactForm() # An unbound form
return render(request, 'webform/contact.html', {'form': form,})



#contact.html within Django
<p>We welcome your questions & comments</p>
<p>Please fill out the form below and hit 'Submit'</p>
<form action="{% url 'webform:contact' %}" method="post">
{% csrf_token %}
{{ form.non_field_errors }}
<table>
<tr><th><label for="id_firstName">First Name:</label></th><td>{{ form.firstName.errors }} {{ form.firstName }}</td></tr>
<tr><th><label for="id_lastName">Last Name:</label></th><td>{{ form.lastName.errors }} {{ form.lastName }}</td></tr>
<tr><th><label for="id_street">Street:</label></th><td>{{ form.street.errors }} {{ form.street }}</td></tr>
<tr><th><label for="id_city">City:</label></th><td>{{ form.city.errors }} {{ form.city }}</td></tr>
<tr><th><label for="id_state">State:</label></th><td>{{ form.state.errors }} {{ form.state }}</td></tr>
<tr><th><label for="id_zipcode">Zipcode:</label></th><td>{{ form.zipcode.errors }} {{ form.zipcode }}</td></tr>
<tr><th><label for="id_phone">Phone:</label></th><td>{{ form.phone.errors }} {{ form.phone }}</td></tr>
<tr><th><label for="id_email">Email:</label></th><td>{{ form.email.errors }} {{ form.email }}</td></tr>
<tr><th><label for="id_message">Message:</label></th><td>{{ form.message.errors }} {{ form.message }}</td></tr>
</table>
<p><input type="submit" value="Submit" /></p>
</form>

UPDATE: Django returning 403 Error -- "CSRF cookie not set"


I discovered this working solution and decided to just disable CSRF protection on these views. I'm going to continue to see if I can test break the site again. Once that is done, i'll deem csrf_exempt as the solution. Ideally keep protection on would be best, but the form I'm using doesn't really need it and I've been at this for too long.




This is an example django template snippet for your form view. Make sure you have {% csrf_token %} within form tags.


<form action="/webform/contact/" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="{% trans 'Create' %}" />
</form>


I've been at this for a few hours. I'm relatively new with Django and I need help in a setup that doesn't seem all that common.


I'm serving my website with Nginx and UWSGI where most of the pages are static and not served using Django. The only reason I'm using Django is for implementing a form. Therefore, I decided to SSI just the form template itself into a <div> within an existing HTML outside of the Django server. The form actually works great when DEBUG = True, but when False the form would render but throws an error when trying to submit. The error is "Forbidden (403) CSRF verification failed. Request aborted. Reason given for failure: CSRF cookie not set." Now the solutions I've found only assume that the whole website is served by Django. However, for me, only a snippet of Django template is served using Nginx's SSI. I'm wondering what the issue is and if the community can help me. Thanks in advance!


HTML outside of Django:  
<div id="formContainer"><!--#include virtual="/webform/contact/" --></div>



#Django view
def contact(request):
if request.method == 'POST': # If the form has been submitted...
form = ContactForm(request.POST) # A form bound to the POST data

if form.is_valid(): #All validation rules pass
# Process the data in form.cleaned_data
firstName = form.cleaned_data['firstName']
lastName = form.cleaned_data['lastName']
street = form.cleaned_data['street']
city = form.cleaned_data['city']
state = form.cleaned_data['state']
zipcode = form.cleaned_data['zipcode']
phone = form.cleaned_data['phone']
email = form.cleaned_data['email']
message = form.cleaned_data['message']

request.session['fname_ses'] = firstName
request.session['lname_ses'] = lastName
request.session['street_ses'] = street
request.session['city_ses'] = city
request.session['state_ses'] = state
request.session['zip_ses'] = zipcode
request.session['phone_ses'] = phone
request.session['email_ses'] = email
request.session['phone_ses'] = phone
request.session['email_ses'] = email
request.session['message_ses'] = message

subject = "A message for _____ from %s %s" %(firstName, lastName)
message_body = ("Here is the personal information provided by the client: \n"
" Full name: %s %s \n"
" Address: %s, %s, %s %s \n"
" Phone: %s \n"
" Email: %s \n \n"
"Message to you: \n \n%s"
%(firstName, lastName, street, city, state, zipcode, phone, email, message)
)
sender = "email1@example.com"
recipients = [
'email1@example.com',
'email2@example.com',
email3@example.com',
]

from django.core.mail import send_mail
send_mail(subject, message_body, sender,
recipients, fail_silently=False)

#Redirect after POST
#reverse() redirects straight to the view instead of the URL
#Use reverse() to prevent URL from appending to current address
return HttpResponseRedirect('webform/thanks_simple.html')
#return HttpResponseRedirect(reverse('webform:thanks'))
else:
form = ContactForm() # An unbound form
return render(request, 'webform/contact.html', {'form': form,})



#contact.html within Django
<p>We welcome your questions & comments</p>
<p>Please fill out the form below and hit 'Submit'</p>
<form action="{% url 'webform:contact' %}" method="post">
{% csrf_token %}
{{ form.non_field_errors }}
<table>
<tr><th><label for="id_firstName">First Name:</label></th><td>{{ form.firstName.errors }} {{ form.firstName }}</td></tr>
<tr><th><label for="id_lastName">Last Name:</label></th><td>{{ form.lastName.errors }} {{ form.lastName }}</td></tr>
<tr><th><label for="id_street">Street:</label></th><td>{{ form.street.errors }} {{ form.street }}</td></tr>
<tr><th><label for="id_city">City:</label></th><td>{{ form.city.errors }} {{ form.city }}</td></tr>
<tr><th><label for="id_state">State:</label></th><td>{{ form.state.errors }} {{ form.state }}</td></tr>
<tr><th><label for="id_zipcode">Zipcode:</label></th><td>{{ form.zipcode.errors }} {{ form.zipcode }}</td></tr>
<tr><th><label for="id_phone">Phone:</label></th><td>{{ form.phone.errors }} {{ form.phone }}</td></tr>
<tr><th><label for="id_email">Email:</label></th><td>{{ form.email.errors }} {{ form.email }}</td></tr>
<tr><th><label for="id_message">Message:</label></th><td>{{ form.message.errors }} {{ form.message }}</td></tr>
</table>
<p><input type="submit" value="Submit" /></p>
</form>

UPDATE: Django returning 403 Error -- "CSRF cookie not set"


I discovered this working solution and decided to just disable CSRF protection on these views. I'm going to continue to see if I can test break the site again. Once that is done, i'll deem csrf_exempt as the solution. Ideally keep protection on would be best, but the form I'm using doesn't really need it and I've been at this for too long.



This is an example django template snippet for your form view. Make sure you have {% csrf_token %} within form tags.


<form action="/webform/contact/" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="{% trans 'Create' %}" />
</form>

0 commentaires:

Enregistrer un commentaire