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>
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