繁体   English   中英

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

[英]How to use csrf_token in Django RESTful API and React?

我以前在Django<\/code>有过经验。 如果在Django<\/code>模板中添加行{csrf_token}<\/code> ,则Django<\/code>处理csrf_token<\/code>的功能。 但是当我尝试使用Django REST Framework<\/code>开发 API 时,我就卡住了。 如何在API<\/code> (后端,使用Django REST Framework<\/code>开发)和React Native\/React JS<\/code> (前端)中添加和处理类似 Django 模板的csrf_token<\/code>等功能?

"

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

现在,从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;
}

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

var csrftoken = getCookie('csrftoken');

接下来,您可以在使用fetch()发送请求时使用此csrf标记,方法是将检索到的标记分配给X-CSRFToken标头。

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

以React Forms呈现CSRF令牌:

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

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

import React from 'react';

var csrftoken = getCookie('csrftoken');

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

然后你可以简单地导入它并在你的表单中调用它

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;

Django CSRF Coo​​kie

React动态呈现组件,这就是为什么如果使用React渲染表单,Django可能无法设置CSRF令牌cookie。 这就是Django docs对此的说法:

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

为了解决这个问题,Django提供了您需要添加到视图函数的ensurecsrfcookie装饰器。 例如:

from django.views.decorators.csrf import ensure_csrf_cookie

@ensure_csrf_cookie
def myview(request):

CSRF是浏览器上下文中的跨站点请求伪造攻击,如果为多客户端提供api,则没有必要。 一般来说Restful api POST请求体是json,你不能在其中添加csrf_token。

但是如果你使用urlencode Post请求体,你可以为所有post请求添加一个intecepto来将csrf_token注入请求体。 我使用此方法将api auth令牌添加到请求标头中

对不起,我的英语不是很好。

我在反应中使用jquery进行ajax,所以在这种情况下这是一个解决方案:

let csrfcookie = function() {  // for django csrf protection
            let cookieValue = null,
                name = "csrftoken";
            if (document.cookie && document.cookie !== "") {
                let cookies = document.cookie.split(";");
                for (let i = 0; i < cookies.length; i++) {
                    let cookie = cookies[i].trim();
                    if (cookie.substring(0, name.length + 1) == (name + "=")) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                    }
                }
            }
            return cookieValue;
};

$.ajax({
       type: "POST",
       beforeSend: function(request, settings) {
                    if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
                        request.setRequestHeader("X-CSRFToken", csrfcookie());
                    }
},

.... /// other codes

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM