Django中间件-跨站请求伪造-Auth模块-seettings实现可插拔配置

---恢复内容开始---

Django中间件

一、什么是中间件

  django中间件就是类似于django的保安;请求来的时候需要先经过中间件,才能到达django后端(url,views,models,templates),

响应走的的时候也需要经过中间件才能到达web服务器网关接口处;

中间件位于web服务端与url路由层之间;是介于request与response处理之间的一道处理过程。

二、中间件有什么用

  如果你想修改请求,例如被传送到view中的HttpRequest对象。 或者你想修改view返回的HttpResponse对象,这些都可以通过中间件来实现。

可以用来做什么?

  1、网站全局的身份校验,访问频率限制,权限检验等;只要涉及到全局校验的都可以用中间件来实现

  2、Django的中间件是所有的web框架中做得最好的

Django默认的中间件:(在django项目的settings模块中,有一个MIDDLEWARE_CLASSES变量,其中的每一个元素就是一个中间件)

django默认的中间件有七个如下图:

 三、自定义中间件

  中间件可以定义五个方法;其中主要的是(process_request:请求 和process_response:返回)

1、process_request(self,request)

2、process_view(self, request, callback, callback_args, callback_kwargs)

3、process_template_response(self,request,response)

4、process_exception(self, request, exception)

5、process_response(self, request, response)

  以上的方法的返回值可以是None或一个HttpResponse对象,如果是None,继续按照Django定义的规则向后继续执行,

如果是HttpResponse对象,则直接将该对象返回给用户即可。

1、process_request和process_response

  当用户发起请求的时候会依次经过所有的的中间件,这个时候的请求时process_request,最后到达views的函数中,views函数处理后,在依次穿过中间件,这个时候是process_response,最后返回给请求者。

如下图所示,一个完整的中间件的流程:

2、完整的Djang启动生命周期:

3、需要重点掌握的中间件方法:

  1、.process_request()方法

    规律:

      1、请求来的时候,会经过每个中间件里面的process_request()方法(从上到下的顺序)

      2、如果返回的是HttpResponse对象,那么会直接返回,不再往下执行了;基于这一特点就可以做访问的频率限制,身份校验,权限校验等

  

  2、process_response()方法

   规律:

    (1)、必须将response形参返回,因为这个形参指代的就是要返回给前端的数据。

    (2)、响应走的时候,会依次经过每一个中间件里面的process_response方法(从下往上)

需要了解的方法:

    (1)、process_view() :

            在路由匹配成功执行视图函数之前 触发

    (2)、process_exception() :

            当你的视图函数报错时  就会自动执行

    (3)、process_template_response() 

            当你返回的HttpResponse对象中必须包含render属性才会触发

 4、自定义的中间件,写的类必须继承 MiddlewareMixin

 (1)第一步:导入

from django.utils.deprecation import MiddlewareMixin

 (2)、自定义中间件,新建文件件书写

from django.utils.deprecation import MiddlewareMixin#
from django.shortcuts import HttpResponse
#
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):在views中定义一个视图视图函数(index)

def index(request):

    print("view函数...")
    return HttpResponse("OK")

(4)、在settings.py的MIDDLEWARE里注册自己定义的中间件

1.如果你想让你写的中间件生效,就必须要先继承MiddlewareMixin
2.在注册自定义中间件的时候,一定要确保路径不要写错

(5)查看运行的结果:得出上面的总结规律

请求得出的规律:

返回得出的规律:

第二种情况,当自定义的中间件种有HttpRsponse时,直接返回:

(6)如果没有返回response形参,因为这个形参指代的就是要返回给前端的数据

 报错结果显示:

 (7)、其他方法了解:

1、process_view

  该方法有四个参数

process_view(self, request, view_func, view_args, view_kwargs)

实例:

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,redirect,render,reverse

class Md1(MiddlewareMixin):
    def process_request(self,request):
        print('Md1请求')
        return HttpResponse("Md1中断")

    def process_response(self,request,response):
        print('Md1返回')
        return response
        # return HttpResponse("嘿嘿!")

    def process_view(self,request,callback,callback_args,callback_kwargs):
        print('Md1views')

class Md2(MiddlewareMixin):
    def process_request(self,request):
        print("Md2请求")
        return HttpResponse('Md2中断')

    def process_response(self,request,response):
        print('Md2返回')
        return response

    def process_view(self,callback,callback_args,callback_kwargs):
        print("Md2views")

2、process_exception,该方法两个参数:

process_exception(self, request, exception)

一个HttpRequest对象

一个exception是视图函数异常产生的Exception对象。

3、process_template_response(self,request,response)方法:

  该方法对视图函数返回值有要求,必须是一个含有render方法类的对象,才会执行此方法

总结:你在书写中间件的时候 只要形参中有repsonse 你就顺手将其返回 这个reponse就是要给前端的消息

 二、CSRF_TOKEN跨站请求伪造

  1、什么是csrf

  CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding;

简单的理解:就是攻击者盗用了你的身份,以你的名义发送恶意的请求,对服务器来说这个请求是完全合法的;

要完成一次CSRF攻击,受害者必须依次完成两个步骤:

  1.登录受信任网站A,并在本地生成Cookie。
  2.在不登出A的情况下,访问危险网站B。

简单的举例钓鱼网站:

正规的网站:

views.py

def transfer(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        money = request.POST.get('money')
        target_user = request.POST.get('target_user')
        print('%s 给 %s 转了 %s元'%(username,target_user,money))
    return render(request,'res.html')

res.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<h2>这是正儿八经的网站</h2>
<form action="//" method="post">
{#    {% csrf_token %}#}
    <p>本人用户名:<input type="text" name="username"></p>
    <p>转账金额:<input type="text" name="money"></p>
    <p>对方账户:<input type="text" name="target_user"></p>
    <input type="submit">
</form>

钓鱼网站破解原理:

  在让用户输入对方账户的那个input上面做手脚,写一个一样的viewx.py,和路由url,

修改前端HTML的内容让转账对方的用户隐藏起来绑定value=’jason‘,启动时修改端口。

 防止钓鱼网站的思路:

  网站会给返回的用户的form表单页面,偷偷的噻一个随机的字符串,请求来的时候,

会先比对随机字符串是否一致,如果不一致,直接拒绝(403)

该随机字符串有一下特点:

  1、同一个浏览器没一次访问都不一样

  2、不同的浏览器之间绝对不会重复

跨站请求伪造的解决方法:

1、form表发送post请求的时候,只需要书写一句话即可

  {% csrf_token %}

书写{% csrf_token %},会在客户端生成一对键值对

2、用AJAX发送post请求时,如何避免csrf校验

  (1)、现在页面上写{% csrf_token %},利用标签查找 ,获取到该input键值信息,关键字:'csrfmiddlewaretoken'

{'username':'jason','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()}

   (2)、直接书写'{{ csrf_token }}'

{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'}

  (3)、你可以将该获取随机键值对的方法,写到一个js文件中,之后只需要导入该文件即可使用。

添加static到settings.Py中:

 然后在使用的前端html页面导入:

书写静态文件存放JS代码:以下代码由官方提供,书写后在需要使用的地方引用即可:

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');


function csrfSafeMethod(method) {
  // these HTTP methods do not require CSRF protection
  return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
  beforeSend: function (xhr, settings) {
    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
      xhr.setRequestHeader("X-CSRFToken", csrftoken);
    }
  }
});

  

  

 

---恢复内容结束---

猜你喜欢

转载自www.cnblogs.com/Gaimo/p/11588026.html