Django 中間件 csrf

返回Django 組件前端

1、中間件​

1.1 什麼是中間件?​​

(1) Django默認自帶7箇中間件,中間件相似於django的門衛,數據在進入和離開時都須要通過中間件

(2) 那麼中間件能幹什麼?
    控制用戶訪問頻率,全局登陸校驗,用戶訪問白名單,黑名單等
    
(3) settings.py裏面的中間件配置信息:
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',
]

(4) 中間件的執行規則:
    1> 數據傳到後端時:按照(3)中的順序,從上到下,依次通過這些中間件處理
    2> 當後端處理完以後,按照從下往上的執行順序,通過這些中間件的處理以後傳到前端
    3> 還有一些規則,會在下面的代碼中講

(5) 中間件中主要有幾個方法:
    process_request(self,request)
    process_view(self, request, callback, callback_args, callback_kwargs)
    process_template_response(self,request,response)
    process_exception(self, request, exception)
    process_response(self, request, response)

1.2 怎麼自定義中間件?

(1) 先導包(單獨的py文件)
    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    
(2) 自定義中間件
    class Md1(MiddlewareMixin):
        def process_request(self,request):
            print("Md1請求")

        def process_response(self,request,response):
            print("Md1返回")
            return response

    class Md2(MiddlewareMixin):
        def process_request(self,request):
            print("Md2請求")
            #return HttpResponse("Md2中斷")
        def process_response(self,request,response):
            print("Md2返回")
            return response
        
(3) 在view中定義一個視圖函數
    def index(request):
        print("view函數...")
        return HttpResponse("OK")
    
(4) 在settings.py中的MIDDLEWARE裏註冊自定義中間件

ps:執行結果
    Md1請求
    Md2請求
    view函數...
    Md2返回
    Md1返回   
    
ps2:若是當請求到達請求2的時候直接不符合條件返回,即return HttpResponse("Md2中斷"),程序將把請求直接發給中間件2返回,而後依次返回到請求者,結果以下:
返回Md2中斷的頁面,後臺打印以下:
    Md1請求
    Md2請求   
    Md2返回
    Md1返回
總結:
    (1) 中間件的process_request方法是在執行視圖函數以前執行的。
    (2) 當配置多箇中間件時,會按照MIDDLEWARE中的註冊順序,也就是列表的索引值,從前到後依次執行的。
    (3) 不一樣中間件之間傳遞的request都是同一個對象。
    
    多箇中間件中的process_response方法是按照MIDDLEWARE中的註冊順序倒序執行的,
    ---> 第一個中間件的process_request方法首先執行,而它的process_response方法最後執行,
    最後一箇中間件的process_request方法最後一個執行,它的process_response方法是最早執行。

2、csrf(跨站請求僞造)

2.1 舉個栗子🌰:

釣魚網站:銀行轉帳的路徑,能夠拿到,而後你作一個跟銀行如出一轍的頁面,也朝銀行的接口提交數據,當用戶在釣魚網站輸入對方帳戶名和轉帳金額以後,點擊發送。其實內部是將對方帳戶換成了釣魚網站的造假人員的帳戶,形成你轉帳轉錯帳戶的狀況。

2.2 如何設置csrf_token

(1) 在form表單中應用
    <form action="" method="post">
        {% csrf_token %}
        <p>用戶名:<input type="text" name="name"></p>
        <p>密碼:<input type="text" name="password"></p>
        <p><input type="submit"></p>
    </form>
    
(2) Ajax中應用
<body>
<form action="" method="post">
    {% csrf_token %}
    <p>用戶名:<input type="text" name="name"></p>
    <p>密碼:<input type="text" name="password" id="pwd"></p>
    <p><input type="submit"></p>
</form>
<button class="btn">點我</button>
</body>
<script>
    $(".btn").click(function () {
        $.ajax({
            url: '',
            type: 'post',
            data: {
                'name': $('[name="name"]').val(),
                'password': $("#pwd").val(),
                'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val()
            },
            success: function (data) {
                console.log(data)
            }
        })
    })
</script>
</html>

2.3 csrf_token使用範圍

# 只想給某個視圖函數加上csrf校驗
from django.views.decorators.csrf import csrf_exempt,csrf_protect

# 局部禁用
@csrf_exempt
def index(request):
  pass

# 局部使用
@csrf_protect
def login(request):
  pass

# CBV比較特殊,不能單獨加在某個方法上
# 只能加在類上或dispatch方法上
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt,csrf_protect

@method_decorator(csrf_exempt,name='dispatch')  # 第一種
class Csrf_Token(View):
  @method_decorator(csrf_exempt)  # 第二種
  def dispatch(self,request,*args,**kwargs):
    res = super().dispatch(request,*args,**kwargs)
    return res
  @method_decorator(csrf_exempt)  # 這裏這麼寫不行!!!
  def get(self,request):
    pass
  def post(self,request):
    pass
相關文章
相關標籤/搜索