(13)Django - CSRF防護(hù)

CSRF(Cross-Site Request Forgery,跨站請(qǐng)求偽造)是一種對(duì)網(wǎng)站的惡意利用,竊取網(wǎng)站的用戶信息來(lái)制造惡意請(qǐng)求。
Django為了防護(hù)這類攻擊,在用戶提交表單時(shí),表單會(huì)自動(dòng)加入csrftoken的隱含值,這個(gè)隱含值會(huì)與網(wǎng)站后臺(tái)保存的csrftoken進(jìn)行匹配。只有匹配成功,網(wǎng)站才會(huì)處理表單數(shù)據(jù)。這種防護(hù)機(jī)制稱為CSRF防護(hù)。
在Django中使用CSRF防護(hù)功能,首先在配置文件settings.py中設(shè)置防護(hù)功能的配置信息,在配置文件的中間件實(shí)現(xiàn),默認(rèn)已開啟。
CSRF防護(hù)只作用于POST請(qǐng)求,并不防護(hù)GET請(qǐng)求,因?yàn)镚ET請(qǐng)求以只讀形式訪問(wèn)網(wǎng)站資源,并不破壞i和篡改網(wǎng)站數(shù)據(jù)。以mysite為例,在模板user.html的表單<form>標(biāo)簽中加入內(nèi)置標(biāo)簽 csrf_token 即可實(shí)現(xiàn)CSRF防護(hù),代碼如下:

#user.html 部分代碼
<form class="form" action="" method="post">
            {% csrf_token %}
            <div>用戶名:<input type="text" name='username'></div>
            <div>密 碼:<input type="password" name='password'></div>
            {% if new_password %}
                <div>新密碼:<input type="password" name='new_password'></div>
            {% endif %}
            <button type="submit" class="btn btn-primary btn-block">確定</button>
</form>

啟動(dòng)運(yùn)行mysite項(xiàng)目,在瀏覽器打開用戶登錄界面,查看頁(yè)面源碼可以發(fā)現(xiàn)表單的隱藏域,隱藏域由模板語(yǔ)法{% csrf_token %}所生成的,網(wǎng)站生成的 csrftoken 都會(huì)記錄在隱藏域的 value 屬性中。當(dāng)用戶每次提交表單時(shí), csrftoken都會(huì)隨之變化。


image.png

如果想要取消表單的 CSRF 防護(hù),可以在模板上刪除{% csrf_token %},并且在相應(yīng)的視圖函數(shù)中添加裝飾器@csrf_exempt,代碼如下:

from django.views.decorators.csrf import csrf_exempt
#取消CSRF防護(hù)
@csrf_exempt
def loginView(request):
    pass
    return render(request, 'user.html', locals())

如果只是在模板上刪除{% csrf_token %},沒(méi)有在相應(yīng)的視圖函數(shù)中設(shè)置過(guò)濾器@csrf_exempt,那么當(dāng)用戶提交表單時(shí),程序會(huì)因CSRF驗(yàn)證失敗而拋出403異常的頁(yè)面。


如果在配置文件settings.py中刪除中間件CsrfViewMiddleware,這樣就使整個(gè)網(wǎng)站都取消CSRF防護(hù)。在全站沒(méi)有 CSRF防護(hù)的情況下,又想對(duì)某些請(qǐng)求設(shè)置CSRF防護(hù),那么在模板上添加模板語(yǔ)法{% csrf_token %},然后再相應(yīng)的視圖函數(shù)中添加裝飾器@csrf_protect即可實(shí)現(xiàn)。

from django.views.decorators.csrf import csrf_protect
#添加CSRF防護(hù)
@csrf_protect
def loginView(request):
    pass
    return render(request, 'user.html', locals())

需要注意的是,在日常開發(fā)中,如果網(wǎng)頁(yè)某些數(shù)據(jù)是使用前端的Ajax實(shí)現(xiàn)表單提交的,那么Ajax向服務(wù)器發(fā)送POST請(qǐng)求時(shí),請(qǐng)求參數(shù)必須添加csrftoken的信息,否則服務(wù)器會(huì)視該請(qǐng)求是惡意請(qǐng)求。代碼如下:

<script>
    function submitForm(){
        var csrf = $('input[name="csrfmiddlewaretoken"]').val();
        var user = $('#user').val();
        var password = $('#password').val();
        $.ajax({
            url:'/csrf1.html',
            type:'POST',
            data:{'user':user,
                'password':password,
                'csrfmiddlewaretoekn':csrf},
            success:function(arg){
                console.log(arg);
            }
        })
}
</script>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容