SoFunction
Updated on 2025-03-04

Solve the problem of Django csrf when posting vue-resource

Some problems encountered by the company recently used vue to write front-end and use vue-resource are now recorded.

vue-resource post data

this.$('/someUrl',data, [options]).then(function(response){
  // Response successfully callback}, function(response){
  // Response to error callback});

vue-resource requests API from the backend. The company's backend is developed using Django. In order to prevent cross-site request forgery, i.e., csrf attack, Django provides CsrfViewMiddleware middleware to defend against csrf attacks.

We add {% csrf %} to the html page to let django render a csrf tag

(If the form is submitted, we need to add this tag to the form tag. If it is submitted in xhr, it will be fine.)

It is not written in the form form, but the implementation effect is the same. We all need to provide csrftoken in the post form. We need to add csrf key to the data we want to transmit in vue.

data{
  csrfmiddlewaretoken: '{{ csrf_token }}' 
}

In this way, when Django parses the form, it will parse to csrf_token, and our post data will not encounter 403 forbidden.

In fact, this is an opportunistic behavior. Although django can also recognize it, it will not work when encountering complex data. For example, when a vue-resource post array, I added an option {emulateJSON: true} to the post option before, so when vue-resource post data, it will convert data into application/x-www-form-urlencoded form format. However, in this way, the post array will be parsed into arrry[0]item. In this way, the backend will not recognize it and will report an error.

The solution is to put csrftoken in the header and pass data on data. The specific solution is to add a

['X-CSRFToken'] = $("input[name='csrfmiddlewaretoken']").val()

where $("input[name='csrfmiddlewaretoken']").val() is the csrftoken in the input generated by django {% csrf %} after the template parsing.

For the header, django will automatically add the HTTP_ prefix when parsing in the background, so our header is X-CSRFToken.

Supplementary knowledge:VUE sends post to django and returns 403: CSRF Failed: CSRF token missing or incorrect

Problem description

The front end is VUE, and the back end is django.

VUE uses axios to send POST code to the backend as follows:

 let params = new URLSearchParams()
  ('orderID', orderId)
  ('dishID', dishId)
  (loginUrL, params})
   .then(response => {
    (response)
    cb()
   })
   .catch(error => {
    (error)
    errorCb()
   })

However, the server returned a 403 error. Click to see, CSRF Failed: CSRF token missing or incorrect

reason

According to this link/a/26639895

This is a cross-domain access issue for django.

django will check legal cross-domain accesses like this. The 'csrftoken' stored in cookies is compared with the field "X-CSRFToken" in the post header. Only when the two matches can the cross-domain test be passed. Otherwise, this error will be returned: CSRF Failed: CSRF token missing or incorrect

Solution

From the above analysis, we can find that as long as you add a field 'X-CSRFToken' to the header of the POST request, this field is the same as the 'csrftoken' in the cookie.

Add a header to the post request, the content is as follows:

{headers: {'X-CSRFToken': ('csrftoken')}

Among them, getCookies is a function that is used to extract the contents in cookies by name:

getCookie (name) {
   var value = '; ' + 
   var parts = ('; ' + name + '=')
   if ( === 2) return ().split(';').shift()
  },

The final POST request is as follows:

  ('orderID', orderId)
  ('dishID', dishId)
  (loginUrL, params, {headers: {'X-CSRFToken': ('csrftoken')}})
   .then(response => {
    (response)
    cb()
   })
   .catch(error => {
    (error)
    errorCb()
   })

The solution to the Django csrf problem in the above vue-resource post data is all the content I share with you. I hope you can give you a reference and I hope you support me more.