pythondjangodjango-templatescsrf-token

Django CSRF token missing in form submission despite including it


I am working on a Django project where I have a form to verify a phone number using Twilio's API. However, I'm encountering an issue where the CSRF token is missing in the form submission, resulting in a "CSRF token missing" error.

I have already included the {% csrf_token %} template tag inside the element in my HTML template. I have also verified that the django.middleware.csrf.CsrfViewMiddleware middleware is enabled in my Django settings.

@login_required
def verify_phone_number(request):
    if request.method == 'POST':
        # Code to initiate phone number verification using Twilio's API
        
        # Code to Return an HTTP response with the HTML content when verification request wasnt sent
        html_content = """
        return HttpResponse(html_content)
    else:
        # Return an HTTP response with the HTML content
        html_content = """
        <!DOCTYPE html>
        <html>
        <head>
            <title>Verify Phone Number</title>
        </head>
        <body>
            <h1>Verify Your Phone Number</h1>

            <form method="post">
                {% csrf_token %}
                <label for="phone_number">Phone Number:</label>
                <input type="text" id="phone_number" name="phone_number" required>
                <button type="submit">Verify</button>
            </form>
        </body>
        </html>
        """
        return HttpResponse(html_content)

Solution

  • You need to render a template in order to use {% csrf_token %}. The way you do it, the actual string {% csrf_token %} will be in your HTML file instead of the Token field.

    You need to put your HTML into a template file, then return a TemplateResponse for the template.

    templates/verify.html:

    <!DOCTYPE html>
            <html>
            <head>
                <title>Verify Phone Number</title>
            </head>
            <body>
                <h1>Verify Your Phone Number</h1>
    
                <form method="post">
                    {% csrf_token %}
                    <label for="phone_number">Phone Number:</label>
                    <input type="text" id="phone_number" name="phone_number" required>
                    <button type="submit">Verify</button>
                </form>
            </body>
            </html>
    

    and then change your code like so:

    @login_required
    def verify_phone_number(request):
        if request.method == 'POST':
            # Code to initiate phone number verification using Twilio's API
            
            # Code to Return an HTTP response with the HTML content when verification request wasnt sent
            return HttpResponse('')
        else:
            # Return an Template response with the HTML content
            return TemplateResponse(request, 'verify.html', {})