安全開發 | 如何讓Django框架中的CSRF_Token的值每次請求都不一樣

前言

用過Django 進行開發的同學都知道,Django框架天然支持對CSRF攻擊的防護,因為其內置了一個名為CsrfViewMiddleware的中間件,其基于Cookie方式的防護原理,相比基于session的方式,更適合目前前后端分離的業務場景,但美中不足的是,其生成的csrf_token在一個session周期中是不變,這對于一些特定的業務場景,顯然有點遺憾。

為了彌補這個遺憾,本文介紹一種不用修改CsrfViewMiddleware中間件源碼的方式,實現基于請求的csrf_token更新方式,詳文如下。

實現過程

1、Django csrf 校驗的兩個場景

在業務場景中,有兩種不同的csrf防護場景,一種是基于Form 表單提交數據的防護,一種是基于ajax 異步請求數據的防護。

對于Form 表單,可以通過在表單中內置`{% csrf_token %}` 實現在提交數據時一起攜帶csrf_token提交上去,從而通過后端csrf 校驗。

這里順便提下 Django模板引擎是如何渲染`{% csrf_token %}`的,其實就是將`{% csrf_token %}` 替換成csrf_input的返回值(這點可從Django 模板引擎源碼中找到),如下:

Django csrf 校驗的兩個場景

而get_token則是從request.META['CSRF_COOKIE']中獲取:

Django csrf 校驗的兩個場景

對于ajax 請求,需要在提交請求的時候,添加一個名為x-csrftoken的頭部(這個頭部是Django源碼中內定的),值為從cookie中提取的指定name的值,這個name可自定義,比如下圖為`csrf-bastion`:

Django csrf 校驗的兩個場景

2、Django csrf token 的生成流程

主要關注下CsrfViewMiddleware 中間件的process_view和process_response。

process_view的主要功能之一就是從請求的cookie中提取指定name的(通過settings.CSRF_COOKIE_NAME指定)cookie值為:csrf token,然后賦值給request.META['CSRF_COOKIE'],如果從請求頭中提取不到,則重新生成,如下圖:

Django csrf token 的生成流程

process_response 中會有更新csrf token cookie的功能,如下:

Django csrf token 的生成流程

3、 通過在視圖中修改request.META['CSRF_COOKIE']值實現csrf token 的更新

通過1和2我們就可以知道只要在在response返回之前更新request.META['CSRF_COOKIE']的值,便可以實現每次請求的csrf token 都不一樣,當然可以通過修改CsrfViewMiddleware中間件源碼的方式實現,不過這種方式的入侵性太大,最好的選擇是在視圖中修改,因為視圖處理流程是在response之前進行,如下:

通過在視圖中修改request.META['CSRF_COOKIE']值實現csrf token 的更新

這里的rotate_token則是CsrfViewMiddleware 中間件提供的更新csrf token的接口,如下:

通過在視圖中修改request.META['CSRF_COOKIE']值實現csrf token 的更新

總結

本文提到的這個方法確實可以實現基于請求對csrf_token值進行更新,而不是原先的基于session的,這樣更新之后,對于ajax請求倒是沒有什么問題,不過對于From表單中csrf_token值的更新是需要進行后端渲染更新的,對于前后端分離的請求,這個不足是可以讓后端提供個token 獲取接口來實現前端頁面中form表單的csrf_token值更新實現,當然也可以對form表單的提交行為進行監聽,然后異步提交,這樣直接走ajax那條路線,就沒啥問題了。

轉載于:https://www.cnblogs.com/h2zZhou/p/9776270.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/388241.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/388241.shtml
英文地址,請注明出處:http://en.pswp.cn/news/388241.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

UNITY3D 腦袋頂血頂名

楊航最近在學Unity3D using UnityEngine; using System.Collections; public class NPC : MonoBehaviour { //主攝像機對象 public Camera camera; //NPC名稱 private string name "我是doud…

一個項目的整個測試流程

最近一直在進行接口自動化的測試工作,同時對于一個項目的整個測試流程進行了梳理,希望能對你有用~~~ 需求分析: 整體流程圖: 需求提取 -> 需求分析 -> 需求評審 -> 更新后的測試需求跟蹤xmind 分析流程: 1. 需…

python度量學習_Python的差異度量

python度量學習Hi folks, welcome back to my new edition of the blog, thank you so much for your love and support, I hope you all are doing well. In today’s learning, we will try to understand about variance and the measures involved in it. Although the blo…

多個攝像機之間的切換

楊航最近在學Unity3D Unity3D入門 第捌章: 多個攝像機之間的切換 內容描述:這章,我們來學習一下同個場景中多個攝像機怎么切換。 接著我們創建一個空對象 GameObject -> Create Empty 命名為CamearController&#xff0…

Kubernetes的共享GPU集群調度

問題背景 全球主要的容器集群服務廠商的Kubernetes服務都提供了Nvidia GPU容器調度能力,但是通常都是將一個GPU卡分配給一個容器。這可以實現比較好的隔離性,確保使用GPU的應用不會被其他應用影響;對于深度學習模型訓練的場景非常適合&#x…

django-celery定時任務以及異步任務and服務器部署并且運行全部過程

Celery 應用Celery之前,我想大家都已經了解了,什么是Celery,Celery可以做什么,等等一些關于Celery的問題,在這里我就不一一解釋了。 應用之前,要確保環境中添加了Celery包。 pip install celery pip instal…

網頁視頻15分鐘自動暫停_在15分鐘內學習網頁爬取

網頁視頻15分鐘自動暫停什么是網頁抓取? (What is Web Scraping?) Web scraping, also known as web data extraction, is the process of retrieving or “scraping” data from a website. This information is collected and then exported into a format that …

Unity3D面試ABC

Unity3D面試ABC 楊航最近在學Unity3D 最先執行的方法是: 1、(激活時的初始化代碼)Awake,2、Start、3、Update【FixUpdate、LateUpdate】、4、(渲染模塊)OnGUI、5、再向后&#xff…

前嗅ForeSpider教程:創建模板

今天,小編為大家帶來的教程是:如何在前嗅ForeSpider中創建模板。主要內容有:模板的概念,模板的配置方式,模板的高級選項,具體內容如下: 一,模板的概念 模板列表的層級相當于網頁跳轉…

2.PHP利用PDO連接方式連接mysql數據庫

代碼如下 <?php$serverName "這里填IP地址";$dbName "這里填數據庫名";$userName "這里填用戶名&#xff08;默認為root&#xff09;";$password "";/*密碼默認不用填*/try { $conn new PDO("mysql:host$serverName;…

django 性能優化_優化Django管理員

django 性能優化Managing data from the Django administration interface should be fast and easy, especially when we have a lot of data to manage.從Django管理界面管理數據應該快速簡便&#xff0c;尤其是當我們要管理大量數據時。 To improve that process and to ma…

3D場景中選取場景中的物體。

楊航最近在學Unity3D&#xfeff;&#xfeff;&#xfeff;&#xfeff;在一些經典的游戲中&#xff0c;需要玩家在一個3D場景中選取場景中的物體。例如《仙劍奇俠傳》&#xff0c;選擇要攻擊的敵人時、為我方角色增加血量、為我方角色添加狀態&#xff0c;通常我們使用鼠標來選…

xpath之string(.)方法

from lxml import etreehtml <li class"tag_1">需要的內容1<a>需要的內容2</a></li> selector etree.HTML(html ) contents selector.xpath ( //li[class "tag_1"]) contents1 selector.xpath ( //li[class "tag…

循環語句

循環語句&#xff1a; 當我們要做一些重復的操作時&#xff0c;首先想到的是有沒有一種循環的語句&#xff1f; 答案當然有 Java提供了三種循環&#xff1a; for循環&#xff0c;在Java5中引入了一種主要用于數組的增強型for循環。while循環do……while循環for循環語法1&#x…

canva怎么使用_使用Canva進行數據可視化項目的4個主要好處

canva怎么使用(Notes: All opinions are my own. I am not affiliated with Canva in any way)(注意&#xff1a;所有觀點均為我自己。我與Canva毫無關系) Canva is a very popular design platform that I thought I would never use to create the deliverable for a Data V…

如何利用Shader來渲染游戲中的3D角色

楊航最近在學Unity3D&#xfeff;&#xfeff; 本文主要介紹一下如何利用Shader來渲染游戲中的3D角色&#xff0c;以及如何利用Unity提供的Surface Shader來書寫自定義Shader。 一、從Shader開始 1、通過Assets->Create->Shader來創建一個默認的Shader&#xff0c;并取名…

深入bind

今天來聊聊bind 關于之前的call跟apply 查看此鏈接 我們要明確4點內容 1. bind之后返回一個函數 let obj {name : skr } function fn(){console.log(this) } let bindfn fn.bind(obj) console.log(typeof bindfn) // function 2.bind改變this 并且可以傳參 bind之后的函數仍…

Css單位

尺寸 顏色 轉載于:https://www.cnblogs.com/jsunny/p/9866679.html

ai驅動數據安全治理_JupyterLab中的AI驅動的代碼完成

ai驅動數據安全治理As a data scientist, you almost surely use a form of Jupyter Notebooks. Hopefully, you have moved over to the goodness of JupyterLab with its integrated sidebar, tabs, and more. When it first launched in 2018, JupyterLab was great but fel…

【Android】Retrofit 2.0 的使用

一、概述 Retrofit是Square公司開發的一個類型安全的Java和Android 的REST客戶端庫。來自官網的介紹&#xff1a; A type-safe HTTP client for Android and JavaRest API是一種軟件設計風格&#xff0c;服務器作為資源存放地。客戶端去請求GET,PUT, POST,DELETE資源。并且是無…