如何在Django RESTful API和React中使用csrf_token?

Tao*_*lam 4 python django django-rest-framework reactjs

我以前有的经验Django。如果{csrf_token}Django模板中添加行,则Django处理的功能csrf_token。但是,当我尝试使用开发API时,Django REST Framework就会陷入困境。如何添加和处理Django csrf_token中的API(后端,使用Django REST Framework)和React Native/React JS(前端)之类的功能?

orv*_*rvi 10

第一步是获取CSRF令牌,该令牌可以从Django csrftoken cookie中检索。

现在,从Django文档中,您可以找到如何通过使用以下简单的JavaScript函数从cookie中获取csrf令牌:

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以通过调用getCookie('csrftoken')函数来检索CSRF令牌

var csrftoken = getCookie('csrftoken');
Run Code Online (Sandbox Code Playgroud)

接下来,通过将检索到的令牌分配给X-CSRFToken标头,可以在通过fetch()发送请求时使用此csrf令牌。

  fetch(url, {
    credentials: 'include',
    method: 'POST',
    mode: 'same-origin',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-CSRFToken': csrftoken
    },
    body: {}
   })
  }
Run Code Online (Sandbox Code Playgroud)

以React形式呈现CSRF令牌:

如果您使用React来渲染表单而不是Django模板,则还需要渲染csrf令牌,因为{ % csrf_token % }客户端无法使用Django标签,因此您需要创建一个使用该getCookie()函数检索令牌并渲染它的高阶组件。任何形式。

让我们在csrftoken.js文件中添加一些行。

import React from 'react';

var csrftoken = getCookie('csrftoken');

const CSRFToken = () => {
    return (
        <input type="hidden" name="csrfmiddlewaretoken" value={csrftoken} />
    );
};
export default CSRFToken;
Run Code Online (Sandbox Code Playgroud)

然后,您可以简单地将其导入并在表单中调用它

import React, { Component , PropTypes} from 'react';

import CSRFToken from './csrftoken';


class aForm extends Component {
    render() {

        return (
                 <form action="/endpoint" method="post">
                        <CSRFToken />
                        <button type="submit">Send</button>
                 </form>
        );
    }
}

export default aForm;
Run Code Online (Sandbox Code Playgroud)

Django CSRF Coo​​kie

React使用动态方式呈现组件,这就是如果您使用React呈现表单时Django可能无法设置CSRF令牌cookie的原因。Django文档是这样说的:

如果您的视图未呈现包含csrftoken template标签的模板,则Django可能未设置CSRF令牌cookie。在将表单动态添加到页面的情况下,这很常见。为了解决这种情况,Django提供了一个视图装饰器来强制设置cookie:surecsrf_cookie()。

为了解决此问题,Django提供了需要添加到视图函数中的surecsrfcookie装饰器。例如:

from django.views.decorators.csrf import ensure_csrf_cookie

@ensure_csrf_cookie
def myview(request):
Run Code Online (Sandbox Code Playgroud)

  • 我用过这个: var cookie = cookies[i].toString().replace(/^([\s]*)|([\s]*)$/g, ""); 而不是 var cookie = jQuery.trim(cookies[i]); 这样你就不需要 jQuery (5认同)