5
votes

I have a contact form in Django for my website and when I was testing it locally it was working fine but now when I try to submit my contact form "live" it always comes up with 403 Forbidden CSRF verification failed.

view:

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            send_mail(
                cd['subject'],
                cd['message'],
                cd.get('email', '[email protected]'),
                ['[email protected]'],
            )
            return HttpResponseRedirect('/thanks/')
    else:
        form = ContactForm()
    return render(request, 'contact/contact.html', {'form': form})

contact.html

{% extends 'site_base.html' %}

{% block head_title %}Contact{% endblock %}

{% block body %}

      <h2>Contact Us</h2>
      <p>To send us a message, fill out the below form.</p>

    {% if form.errors %}
        <p style="color: red;">
            Please correct the error{{ form.errors|pluralize }} below.
        </p>
    {% endif %}

    <form action="" method="POST">
    {% csrf_token %}
        <table>
            {{ form.as_table }}
        </table>
        <br />
        <button type="submit" value="Submit" class="btn btn-primary">Submit</button>
    </form>    

{% endblock %}

settings (the ones I thought would be relevant):

SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
MIDDLEWARE_CLASSES = [
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

After trying to rule out some things, here's what I discovered. When I comment out SESSION_COOKIE_SECURE = TRUE and CSRF_COOKIE_SECURE = TRUE and SESSION_EXPIRE_AT_BROWSER_CLOSE = TRUE it works no problem.

If I just comment out CSRF_COOKIE_SECURE = TRUE it works fine. Something weird seems to be going on with how I'm handling CSRF... any help would be great.

1
Are you serving your site over https? Is the entire site like that, or just the form submission? If the browser is initially sent the cookie over http I don't think it will return it on form submission over https.Kevin Christopher Henry

1 Answers

7
votes

Sounds to me like the site is not https if it works when you comment out that line? CSRF_COOKIE_SECURE=True makes the csrf token only work with ssl per the docs https://docs.djangoproject.com/en/1.7/ref/settings/#csrf-cookie-secure