最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Django防御csrf攻擊的實(shí)現(xiàn)方式(包括ajax請求)

 更新時(shí)間:2023年09月19日 08:50:44   作者:he-yin  
這篇文章主要介紹了Django防御csrf攻擊的實(shí)現(xiàn)方式(包括ajax請求),具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

csrf攻擊簡要說明

用戶A現(xiàn)在登錄了某銀行網(wǎng)站的官網(wǎng),瀏覽器記錄了該網(wǎng)站生成的記錄用戶信息的cookie,而后用戶A點(diǎn)擊了釣魚網(wǎng)站(該網(wǎng)站和銀行網(wǎng)站長的一樣),該釣魚網(wǎng)站內(nèi)有js代碼向銀行官網(wǎng)發(fā)起轉(zhuǎn)賬請求,此時(shí)該請求會(huì)自動(dòng)攜帶記錄用戶信息的cookie值去訪問銀行官網(wǎng)進(jìn)行轉(zhuǎn)賬操作,銀行網(wǎng)站的后端若沒有設(shè)置csrf防御機(jī)制,僅僅驗(yàn)證用戶是否登錄,就會(huì)認(rèn)為該轉(zhuǎn)賬操作是該用戶的合法操作。如果銀行網(wǎng)站不僅驗(yàn)證cookie,同時(shí)再驗(yàn)證一個(gè)攻擊者無法獲取到的值,就能防御上述漏洞。

CsrfViewMiddleware中間件

Django防御csrf攻擊是通過 django.middleware.csrf.CsrfViewMiddleware 中間件實(shí)現(xiàn)的,當(dāng)我們創(chuàng)建項(xiàng)目后,默認(rèn)在 settings 文件內(nèi)的 MIDDLEWARE 內(nèi)已經(jīng)開啟了該中間件

防御機(jī)理:驗(yàn)證cookie中的 csrftoken 值和表單中 csrfmiddlewaretoken (或ajax請求頭中的X-CSRFToken參數(shù))的值,兩者里邊的secret是否相同(不是完整的token值是否相同)來進(jìn)行防御(這個(gè)值攻擊者無法獲取到)。

原因:由于瀏覽器同源策略的限制,釣魚網(wǎng)站無法獲取銀行網(wǎng)站給用戶設(shè)置的cookie,也就無法獲取csrftoken值,自然就無法在form表單或ajax請求頭中偽造該值,而django是要驗(yàn)證這兩個(gè)值的secret是否是一致的

非ajax請求實(shí)現(xiàn)

該方法即form標(biāo)簽的action屬性直接提交表單數(shù)據(jù),當(dāng)使用這種方式時(shí),只需要在模板內(nèi)使用 {% csrf_token %} (必須在form表單內(nèi)) 即可實(shí)現(xiàn)防御,代碼如下:

<form method="post" action="/login/">
	{% csrf_token %}
</form>

注意:在視圖函數(shù)內(nèi)return響應(yīng)時(shí),如果不是使用的render()函數(shù),則需要確保 RequestContext 被用于渲染模板(render函數(shù)是自帶上下文管理器的),否則 {% csrf_token %} 無法正常工作

{% csrf_token %} 作用:

1、在form表單內(nèi)生成一個(gè)input標(biāo)簽,內(nèi)容為

<input type="hidden" name="csrfmiddlewaretoken" value="jojovCfhvZhhqhbVf82BkzOA9EGIgPheBt3H0obOxygwCp4NHxcZ1tjhBbPl62DE">

2、在響應(yīng)中設(shè)置cookie csrftoken=dArgJ7X1ygDM2lyau37guxRkwDR1lbd3vFbzeTTyAPC1etr2WshEbrm1Ya0Ebozt

ajax請求實(shí)現(xiàn)

現(xiàn)實(shí)開發(fā)中,我們可能更多的使用ajax的方式進(jìn)行請求。

ajax的方式需要在請求頭上設(shè)置 X-CSRFToken 參數(shù)來記錄csrftoken的值,因此問題變成了如何獲取csrftoken的值。

django提供了幾種方式來獲取該值,首先要區(qū)分 CSRF_USE_SESSIONS 是否開啟,該參數(shù)表示是否將CSRF token 存儲(chǔ)在session中而不是cookie中,一般情況下無需修改此值,默認(rèn)是False。

django官方例子是從cookie中獲取csrftoken。

CSRF_USE_SESSIONS 為False的情況

在此情形下,有兩種方式來確保響應(yīng)的cookie中有 csrftoken 這個(gè)值

1、在模板中添加  {% csrf_token %}(任意位置) ,則響應(yīng)的cookie中自然會(huì)有csrftoken

2、模板中沒有添加  {% csrf_token %} ,那么在視圖函數(shù)上添加裝飾器 `ensure_csrf_cookie`就會(huì)強(qiáng)制在響應(yīng)頭中添加 csrftoken這個(gè)cookie

從cookie中獲取值的js代碼

// using jQuery
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]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');

或者直接使用js的Cookie庫來獲取

var csrftoken = Cookies.get('csrftoken');

上述僅描述從cookie中獲取csrftoken,如果模板中設(shè)置了 {% csrf_token %} ,那么無論從cookie還是dom取值都是可以的

CSRF_USE_SESSIONS 為True的情況

此種方式若要獲取csrftoken,就要求必須在html中存在 csrftoken(不能在cookie中獲取該值),并使用js從dom中獲取該值,也就是說必須在模板中添加 {% csrf_token %}(任意位置)

{% csrf_token %}
<script type="text/javascript">
// using jQuery
var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
</script>

在ajax請求中設(shè)置token

代碼如下:

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
// 在jquery的每個(gè)請求發(fā)起前設(shè)置X-CSRFToken
$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

以上步驟總結(jié)起來就是:

1、獲取csrftoken值(從cookie或dom中獲取,給cookie中設(shè)置該值的兩種方法)

2、在ajax請求頭中設(shè)置 X-CSRFToken 記錄csrftoken值

3、發(fā)起ajax請求即可

前后端完全分離開發(fā)

在此種情形下,html頁面不由django渲染返回(html頁面作為靜態(tài)文件處理,所有數(shù)據(jù)均為異步加載),因此無法通過上述幾種方式來獲取csrftoken的值

通過了解 CsrfViewMiddleware 可知,為form表單生成csrftoken是通過 get_token(request) 函數(shù)實(shí)現(xiàn)的,源碼如下:

def get_token(request):
    """
    Return the CSRF token required for a POST form. The token is an
    alphanumeric value. A new token is created if one is not already set.
    A side effect of calling this function is to make the csrf_protect
    decorator and the CsrfViewMiddleware add a CSRF cookie and a 'Vary: Cookie'
    header to the outgoing response.  For this reason, you may need to use this
    function lazily, as is done by the csrf context processor.
    """
    if "CSRF_COOKIE" not in request.META:
        csrf_secret = _get_new_csrf_string()
        request.META["CSRF_COOKIE"] = _salt_cipher_secret(csrf_secret)
    else:
        csrf_secret = _unsalt_cipher_token(request.META["CSRF_COOKIE"])
    request.META["CSRF_COOKIE_USED"] = True
    return _salt_cipher_secret(csrf_secret)

編寫視圖函數(shù)用來返回token值:

def get_token(request):
    token = django.middleware.csrf.get_token(request)
    return JsonResponse({'token': token})

前端代碼:

var csrftoken;
$.get('/csrf_token/', function (resp) {
    csrftoken = resp.token;  // 接受上邊視圖函數(shù)返回的token,保存到全局變量中
    document.cookie = 'csrftoken=' + resp.token;  // token設(shè)置到cookie中
});
// 將csrftoken設(shè)置到ajax的請求頭上
function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
// 在jquery的每個(gè)請求發(fā)起前設(shè)置X-CSRFToken
$.ajaxSetup({
    beforeSend: function (xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});
// 下邊發(fā)起ajax請求即可

取消防御的幾種手段

1、完全取消防御,直接注釋掉 settings 中的 django.middleware.csrf.CsrfViewMiddleware 即可

2、少數(shù)視圖函數(shù)取消防御,使用 csrf_exempt 來裝飾視圖函數(shù)即可

3、少數(shù)視圖函數(shù)需要防御,先注釋掉 settings 中的 django.middleware.csrf.CsrfViewMiddleware ,在需要防御的視圖函數(shù)使用 csrf_protect 裝飾器即可

4、如果在 CsrfViewMiddleware 中間件執(zhí)行之前,視圖函數(shù)先執(zhí)行了(如返回404,500等頁面),此時(shí)仍然需要確保{% csrf_token %}能夠起作用,使用requires_csrf_token裝飾器

參考鏈接:https://docs.djangoproject.com/zh-hans/2.0/ref/csrf/

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python如何批量處理經(jīng)緯度數(shù)據(jù)并生成位置信息

    Python如何批量處理經(jīng)緯度數(shù)據(jù)并生成位置信息

    這篇文章主要介紹了Python如何批量處理經(jīng)緯度數(shù)據(jù)并生成位置信息問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • python將下載到本地m3u8視頻合成MP4的代碼詳解

    python將下載到本地m3u8視頻合成MP4的代碼詳解

    這篇文章主要介紹了python將下載到本地m3u8視頻合成MP4的代碼詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • pytorch中.to(device) 和.cuda()的區(qū)別說明

    pytorch中.to(device) 和.cuda()的區(qū)別說明

    這篇文章主要介紹了pytorch中.to(device) 和.cuda()的區(qū)別說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • 深入了解Python中的變量

    深入了解Python中的變量

    這篇文章主要為大家介紹了Python的變量,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • python如何將aac轉(zhuǎn)為mp3,保持原有目錄結(jié)構(gòu)

    python如何將aac轉(zhuǎn)為mp3,保持原有目錄結(jié)構(gòu)

    使用Python腳本實(shí)現(xiàn)AAC格式轉(zhuǎn)MP3格式的方法介紹,需要用戶輸入AAC文件所在目錄路徑和MP3輸出目錄路徑,通過調(diào)用FFmpeg工具實(shí)現(xiàn)格式轉(zhuǎn)換,該腳本簡單易懂,適合需要批量處理音頻文件的用戶,使用前需確保已安裝FFmpeg環(huán)境
    2024-11-11
  • Django項(xiàng)目打包完整步驟以及可能出現(xiàn)的問題

    Django項(xiàng)目打包完整步驟以及可能出現(xiàn)的問題

    django項(xiàng)目的結(jié)構(gòu)大體上都是類似,打包主要的功能就是把一些不需要部署的文件剔除,把需要部署的文件直接壓縮打包,下面這篇文章主要給大家介紹了關(guān)于Django項(xiàng)目打包完整步驟以及可能出現(xiàn)問題的相關(guān)資料,需要的朋友可以參考下
    2023-06-06
  • Python中的高級函數(shù)map/reduce使用實(shí)例

    Python中的高級函數(shù)map/reduce使用實(shí)例

    這篇文章主要介紹了Python中的高級函數(shù)map/reduce使用實(shí)例,Python內(nèi)建了map()和reduce()函數(shù),本文就講解如何使用它,需要的朋友可以參考下
    2015-04-04
  • python中的集合及集合常用的使用方法

    python中的集合及集合常用的使用方法

    這篇文章主要介紹了python中的集合及集合常用的使用方法,集合是一個(gè)無序的不重復(fù)元素序列,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-07-07
  • python+selenium實(shí)現(xiàn)登錄賬戶后自動(dòng)點(diǎn)擊的示例

    python+selenium實(shí)現(xiàn)登錄賬戶后自動(dòng)點(diǎn)擊的示例

    本篇文章主要介紹了python+selenium實(shí)現(xiàn)登錄賬戶后自動(dòng)點(diǎn)擊的示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-12-12
  • pip?install?python-Levenshtein失敗的解決

    pip?install?python-Levenshtein失敗的解決

    這篇文章主要介紹了pip?install?python-Levenshtein失敗的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02

最新評論

塘沽区| 聂荣县| 德昌县| 额敏县| 万载县| 专栏| 专栏| 石渠县| 凉城县| 金阳县| 汽车| 惠来县| 旌德县| 黄山市| 资中县| 井陉县| 江门市| 小金县| 香格里拉县| 开原市| 泾阳县| 绥棱县| 宁波市| 乌兰察布市| 板桥市| 贺兰县| 九台市| 徐州市| 顺义区| 富宁县| 洪江市| 松阳县| 富蕴县| 佛山市| 尚志市| 大庆市| 昭觉县| 泰来县| 南充市| 长治县| 沅陵县|