簡體   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