溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Django CSRF 簡(jiǎn)述

發(fā)布時(shí)間:2020-07-14 19:51:58 來(lái)源:網(wǎng)絡(luò) 閱讀:867 作者:beanxyz 欄目:開(kāi)發(fā)技術(shù)

CSRF(Cross-site request forgery),中文名稱是跨站請(qǐng)求偽造。什么意思呢?簡(jiǎn)單的說(shuō),就是用戶在網(wǎng)站A登錄之后,網(wǎng)站生成了對(duì)應(yīng)的Cookie等信息,然后這個(gè)時(shí)候,用戶又打開(kāi)了網(wǎng)站B,網(wǎng)站B可以在提交表單的時(shí)候,指定對(duì)象的地址為網(wǎng)站A,這樣就對(duì)網(wǎng)站A提出了一個(gè)請(qǐng)求。


為了避免這種惡意請(qǐng)求,一般的方法是在客戶端生成一個(gè)Token,每次提交來(lái)的請(qǐng)求,服務(wù)器都會(huì)驗(yàn)證這個(gè)Token之后才會(huì)放行。Django里面,默認(rèn)配置文件里面有一個(gè)中間件,可以幫我們實(shí)現(xiàn)這個(gè)功能。


MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]


在前面的例子里面,我們都是注釋掉了csrf這個(gè)中間件。因?yàn)橐坏┦褂玫脑?,?huì)自動(dòng)在Cookie里面生成一個(gè)CSRFToken。相對(duì)應(yīng)的,在模板文件里面我們也必須提供對(duì)應(yīng)的csrftoken,否則提交post請(qǐng)求的時(shí)候,就會(huì)出現(xiàn)下面的錯(cuò)誤。

Django CSRF 簡(jiǎn)述


在打開(kāi)著CSRF的中間件之后,如果觀察Cookie,會(huì)發(fā)現(xiàn)他自動(dòng)生成了一個(gè)csrftoken的鍵值對(duì)。



Django CSRF 簡(jiǎn)述


如何使用呢?最簡(jiǎn)單的方式就是在模板文件的form里面添加一行 {% csrf_token %},這樣就行了

<form action="/login/" method="POST">
        {% csrf_token %}
        <input type="text" name="user" />
        <input type="text" name="pwd" />
        <input type="checkbox" name="rmb" value="1" /> 10秒免登錄
        <input type="submit" value="提交" />
        <input id="btn1" type="button" value="按鈕" />
        <input id="btn2" type="button" value="按鈕" />
    </form>


除了POST提交數(shù)據(jù),我們還可以通過(guò)AJAX來(lái)提交數(shù)據(jù)。那么在AJAX里面應(yīng)該如何使用呢?有兩種方式:

  1. 可以在具體的一個(gè)AJAX請(qǐng)求里面添加一個(gè)header,header里面的csrftoken通過(guò)cookie獲取


$('#btn1').click(function () {
                $.ajax({
                    url: '/login/',
                    type:"GET",
                    data: {'user': 'root', 'pwd': '123'},
                    headers: {'X-CSRFtoken': $.cookie('csrftoken')},
                    success:function(arg){
                    }
                })
            });


2.我們還可以針對(duì)所有的AJAX請(qǐng)求統(tǒng)一配置,這樣在執(zhí)行AJAX發(fā)送之前 會(huì)自動(dòng)執(zhí)行下面的代碼

$.ajaxSetup({
                beforeSend: function(xhr,settings){
                    xhr.setRequestHeader('X-CSRFtoken', $.cookie('csrftoken'));
                }
            });


除了通過(guò)中間件全局的配置CSRF,我們還可以進(jìn)行局部的調(diào)整,允許或者不允許執(zhí)行CSRF。


Django提供了兩個(gè)裝飾器函數(shù) csrf_exempt 和csrf_protector。


我們?nèi)绻P(guān)閉了全局的CSRF,但是又希望對(duì)個(gè)別函數(shù)進(jìn)行保護(hù),可以在對(duì)應(yīng)的函數(shù)上面使用csrf_protector這個(gè)裝飾器。(不推薦)


例如:

from django.views.decorators.csrf import csrf_exempt,csrf_protect
@csrf_protect
def index(request):
    print(request.session)


另外一個(gè)情況就是,我們打開(kāi)了全局的CSRF,但是希望對(duì)個(gè)別函數(shù)不進(jìn)行保護(hù),那么使用csrf_exempt

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI