Search code examples
pythondjangojekyllcsrf

Add CSRF token to hard coded Django form


I am building a static page with Jekyll that has a hard coded form, I am sending the form data to a Django server, I am having trouble generating a CSRF token. The only way I could get the data to save to the database was if I used a static csrf token which is hacky and pointless.

Is there a better way this can be done?

This is what I want:

<form method="POST" action="http://djangoserver" >
    {% csrf_token %} <!-- Doesn't work in Jekyll -->
    <input type="text" name="name" required id="id_name" maxlength="100>
 </form>

But obviously Jekyll doesn't know what that token is, and the POST doesn't send it to the Django Server.


This works, but it is vulnerable and hacky, I need the same effect that actually generates a unique token every time.

<form method="POST" action="http://djangoserver" >
    <input type="hidden" name="csrfmiddlewaretoken" value=" some long stuff" >
    <input type="text" name="name" required id="id_name" maxlength="100>
 </form>

Solution

  • The {% csrf_token %} won't work because it's a Django template tag. Hardcoding a csrfmiddlewaretoken wouldn't work either because this value change so to provide the security.

    I had a similar issue on my blog which is Jekyll as well. On a contact page I added the normal HTML form with the action pointing to my Django backend. For this view, I removed the CSRF token verification using the @csrf_exempt decorator.

    To avoid abuse, I added a Google Recaptcha verification.

    See below an example:

    from django.conf import settings
    from django.views.decorators.csrf import csrf_exempt
    from django.views.decorators.http import require_POST
    import requests  # http://docs.python-requests.org
    
    @require_POST
    @csrf_exempt
    def ask(request):
        recaptcha_response = request.POST.get('g-recaptcha-response')
        data = {
            'secret': settings.GOOGLE_INVISIBLE_RECAPTCHA_SECRET_KEY,
            'response': recaptcha_response
        }
        r = requests.post('https://www.google.com/recaptcha/api/siteverify', data=data)
        result = r.json()
    
        if result['success']:
            # process form...
        else:
            # invalid recaptcha