0

I'm developing my first project and have been blocked by CSRF for the last 4 days.

What I need to try and accomplish is:

  1. Authenticated user should submit an angular form to a django rest_framework api.

  2. The info submitted to the django api should then be used to submit a soap request to a 3rd party wsdl service.

  3. The response should then be saved to a .pdf file and rendered on the page.

I'm currently stuck on the first point of this process and have not even started on point 2 and 3 as point 1.

Error

Forbidden (CSRF token missing or incorrect.)

person_search_new.html:

<!DOCTYPE html>

<html lang="en">

{% extends 'base/base.html' %}
{% block title %}Person Search{% endblock %}
{% load static %}


  <body>

    <!-- Navigation -->

    {% block body %}

      <!-- Page Content -->
      <div class="container">

        <!-- Page Heading/Breadcrumbs -->
        <h1 class="mt-4 mb-3">Intelligence Portal
          <small>Person Search</small>
        </h1>

        {% if user.is_authenticated %}
          <p>
            User: {{ user.get_username }}
          </p>

          <ol class="breadcrumb">
            <li class="breadcrumb-item">
              <a href="{% url 'member:member' %}">Member Zone</a>
            </li>
            <li class="breadcrumb-item">
              <a href="{% url 'intelportal:intelportal' %}">Intelligence Portal</a>
            </li>
            <li class="breadcrumb-item active">Person Search</li>
          </ol>

          <!-- Content Row -->
          <div class="row">
            <!-- Sidebar Column -->
            <div class="col-lg-3 mb-4">
              {% include 'base/sidebar_template.html' %}
            </div>
            <!-- Content Column -->
            <div class="col-lg-9 mb-4">
              <h2>Person Search</h2>
              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Soluta, et temporibus, facere perferendis veniam beatae non debitis, numquam blanditiis necessitatibus vel mollitia dolorum laudantium, voluptate dolores iure maxime ducimus fugit.</p>

              <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
              <script src="{% static 'intelportal/person_search_form_new.js' %}"></script>
              <script src="{% static 'intelportal/form_builder_config.js' %}"></script>

              <div ng-app="formBuilder">
                  {% csrf_token %}
                  {% verbatim %}
                  <div ng-controller="personSearchController">
                    <div class="form-group">
                        <form class="form-control" action="" method="post" enctype="multipart/form-data">
                            <div class="control-group form-group">
                                <label>
                                    <input type="radio" ng-model="selectedType" value="idNumber">
                                    ID Number
                                </label>
                                <label>
                                    <input type="radio" ng-model="selectedType" value="passportNumber">
                                    Passport Number
                                </label>
                                <label>
                                    <input type="radio" ng-model="selectedType" value="initialsSurnameDob">
                                    Initials, Surname and Date of Birth
                                </label>
                            </div>
                                <div ng-switch="selectedType">
                                    <div ng-switch-when="idNumber">
                                        <p>
                                            <label>
                                                ID Number:
                                                <input type="text" ng-model="idNumberInput" name="idNumber" placeholder="ID Number" ng-required="true">
                                            </label>
                                        </p>
                                        <p>
                                            <label>
                                                Your Reference:
                                                <input type="text" ng-model="yourReferenceInput" name="yourReference" placeholder="Your Reference" ng-required="true">
                                            </label>
                                        </p>
                                        <p>
                                            <button ng-click="add(idNumberInput, yourReferenceInput)" type="submit" class="btn btn-primary">Submit</button>
                                        </p>
                                    </div>
                                    <div ng-switch-when="passportNumber">
                                        <p>
                                            <label>
                                                Passport Number:
                                                <input type="text" ng-model="passportNumberInput" name="passportNumber" placeholder="Passport Number" ng-required="true">
                                            </label>
                                        </p>
                                        <p>
                                            <label>
                                                Your Reference:
                                                <input type="text" ng-model="yourReferenceInput" name="yourReference" placeholder="Your Reference" ng-required="true">
                                            </label>
                                        </p>
                                        <p>
                                            <button ng-click="submit(passportNumberInput, yourReferenceInput)" type="submit" class="btn btn-primary">Submit</button>
                                        </p>
                                    </div>
                                    <div ng-switch-when="initialsSurnameDob">
                                        <p>
                                            <label>
                                                Initials / Forenames:
                                                <input type="text" ng-model="initialsInput" name="initials" placeholder="Initials / Forenames" ng-required="true">
                                            </label>
                                        </p>
                                        <p>
                                            <label>
                                                Surname:
                                                <input type="text" ng-model="surnameInput" name="surname" placeholder="Surname" ng-required="true">
                                            </label>
                                        </p>
                                        <p>
                                            <label>
                                                Date of Birth:
                                                <input type="text" ng-model="dobInput" name="dob" placeholder="Date of Birth" ng-required="true">
                                            </label>
                                        </p>
                                        <p>
                                            <label>
                                                Your Reference:
                                                <input type="text" ng-model="yourReferenceInput" name="yourReference" placeholder="Your Reference" ng-required="true">
                                            </label>
                                        </p>
                                        <p>
                                            <button ng-click="submit(initialsInput, surnameInput, dobInput, yourReferenceInput)" type="submit" class="btn btn-primary">Submit</button>
                                        </p>
                                    </div>
                                </div>
                        </form>
                    </div>
                  </div>
              </div>
                  {% endverbatim %}

            </div>
          </div>
          <!-- /.row -->



        {% else %}

          <br>
            <p>
              This area requires member authentication. Please log in with your authorised member account.
            </p>
            <p>
              <a href="{% url 'member:login' %}">Go to login</a>
            </p>
          </br>

        {% endif %}

      </div>

    {% endblock %}

    <!-- /.container -->

    <!-- Footer -->

    <!-- Bootstrap core JavaScript -->

  </body>

</html>

api.py:

from rest_framework.viewsets import ModelViewSet
from .serializers import PersonIdNumberSerializer
from .models import NormalSearch
from rest_framework import views, status, permissions

class PersonIdNumberViewSet(ModelViewSet):
    login_required = True
    queryset = NormalSearch.objects.all()
    serializer_class = PersonIdNumberSerializer
    permission_classes = (permissions.IsAuthenticated,)

views.py

class PersonSearchView(TemplateView):
    template_name = 'intelportal/person_search_new.html'
    login_required = True

urls.py

from django.urls import path, include
from . import views
from .api import PersonIdNumberViewSet
from rest_framework.routers import DefaultRouter


app_name = 'intelportal'

router = DefaultRouter()
router.register(r'persons', PersonIdNumberViewSet, base_name='persons')

urlpatterns = [
    path('person_search', views.PersonSearchView.as_view(), name='person_search'),
    path('', views.IntelPortalView.as_view(), name='intelportal'),
    path('person_search/', include(router.urls)),

    ]

person_search_form_new.js (.js controller)

(function(){
     'use strict';
    angular.module('formBuilder', [])
      .controller('personSearchController', ['$scope', '$http', personSearchControllerFunction]);

       function personSearchControllerFunction($scope, $http){
            $scope.submit = function(idNumber,reference){
                var person = {
                    list: list.id,
                    idNumber: idNumber,
                    reference: reference,
                };
                $http.post('/intelportal/person_search/persons/', person)
                    .then(function(response){
                        list.person.push = (response.data);
                    },
                    function(){
                        alert('Could not create query')
                    });
            };
            $scope.data = [];
            $http.get('/intelportal/person_search/persons/')
                .then(function(response){
                    $scope.data = response.data;
                });
       };
})();

form_builder_config.js (.js config)

(function(){
    'use strict';

    angular.module('formBuilder')
        .run(['$http', run]);

    function run($http){
        $http.defaults.xsrfHeaderName = 'X-CSRFToken';
        $http.defaults.xsrfCookieName = 'csrftoken';
    }

})();

I truly hope there is someone that can shed light on this as I don't have any hair left to pull out :)

Mikhail Kholodkov
  • 23,642
  • 17
  • 61
  • 78
normski
  • 1
  • 1
  • `{% csrf_token %}` should be inside the *
    * and *
    *
    – Waket Zheng Jun 07 '18 at 09:47
  • This doesn't seem to solve the problem. It only prints the text {% csrf_token %} into the form. – normski Jun 07 '18 at 10:46
  • I removed {% verbatim %} {% endverbatim %} and left {% csrf_token %} inside the
    and
    but, now I'm getting the following error Method Not Allowed (POST): /intelportal/person_search [07/Jun/2018 12:50:43] "POST /intelportal/person_search HTTP/1.1" 405 0. I find this strange because I'm expecting to see /intelportal/person_search/persons/ like the get request "GET /intelportal/person_search/persons/ HTTP/1.1" 200 61
    – normski Jun 07 '18 at 10:55
  • Have you try this https://stackoverflow.com/questions/18156452/django-csrf-token-angularjs – Waket Zheng Jun 07 '18 at 10:57
  • yes its in form_builder_config.js – normski Jun 07 '18 at 11:01
  • I spent more than one week to bear down the *csrf* several months ago. It was hard, and I tried many ways. But I used Vue and not fimilar with *Angular*. So I wish you go luck. ^-^ – Waket Zheng Jun 08 '18 at 08:46
  • I managed to resolve the 405 error as well. I added my action="/intelportal/person_search/persons/" to my form. Now I get no errors, however the form data is not submitted to my api and the .api just returns "This field is required." At least I know what that my field validation works :).....and so we continue with no results..... – normski Jun 08 '18 at 12:24
  • Maybe you can push your code to github to get help. – Waket Zheng Jun 10 '18 at 03:42

0 Answers0