django中间件和csrf_token

django中间件

http协议
    #四大特性
    1. 基于请求响应
    2. 基于tcp/udp协议之上
    3, 无状态
    4. 无/短链接
    #请求格式
       请求首行(http协议版本,当前请求的方式)
       请求头(一大堆k,v键值对)
       /r/n
       请求体(存放的是一些数据,并不是每种请求方式都有请求体,get没有请求体,post有)
    #响应状态码
       简单的说就是用一串数字来表示一些复杂的状态或者描述性信息
   1xx:
       服务端已经接受到你的数据正在处理,你可以继续提交数据
   2xx:
       服务器端成功响应你的数据(200)
   3xx:
       重定向
   4xx:
       找不到你需要的数据或不符合获得数据的条件(403,404)
   5xx:
       服务器端出现故障(500)
    #url:统一资源定位符:(网址)

"""
django中间件是django的门户
1.请求来的时候需要先经过中间件才能到达真正的django后端
2.响应走的时候最后也需要经过中间件才能发送出去

django自带七个中间件
"""
django请求生命周期流程图

研究django中间件代码规律
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',
]

class SessionMiddleware(MiddlewareMixin):
    def process_request(self, request):
        session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
        request.session = self.SessionStore(session_key)
    def process_response(self, request, response):
        return response
      
class CsrfViewMiddleware(MiddlewareMixin):
      def process_request(self, request):
        csrf_token = self._get_token(request)
        if csrf_token is not None:
            # Use same token next time.
            request.META['CSRF_COOKIE'] = csrf_token
    def process_view(self, request, callback, callback_args, callback_kwargs):
        return self._accept(request)

    def process_response(self, request, response):
        return response
      
class AuthenticationMiddleware(MiddlewareMixin):
    def process_request(self, request):
        request.user = SimpleLazyObject(lambda: get_user(request))
"""
django支持程序员自定义中间件并且暴露给程序员五个可以自定义的方法
    1.必须掌握
        process_request

  执行顺序是中间件的注册顺序, 从上到下


        process_response

  执行顺序是中间件的注册倒序, 从下到上


    2.了解即可
        process_view
   urls.py 之后, views.py之前执行, 中间件注册的顺序执行

              
        process_template_response
        返回的对象中必须要render属性才会触发


        process_exception

  视图有异常才会触发
"""

如何自定义中间件

1. 在项目名或引用下创建一个任意名称的文件夹

2. 在该文件夹内创建一个任意名称的py文件

3. 在py文件中书写类(这个类必须继承MiddlewareMixin)

  然后就可以在这个类中定义五个方法了

4. 将类的路径以字符串的形式注册到配置文件中

五个方法

必须掌握

def process_request(self, request):

  1. 请求来的时候需要经过每一个中间里面的process_request方法, 结果的顺序是按照配置文件中注册的中间价的顺序从上往下执行

  2. 如果中间价里面没有定义该方法, 直接跳过执行下一个中间价

  3. 如果该方法返回了HTTPResponse对象, name请求不在继续往下执行, 而是直接原路返回

  process_request方法就是用来做全局相关的所有限制功能

 

def process_response(self, request, process):

  1. 响应走的时候需要经过每一个中间价里面的process_response方法, 该方法有两个额外的参数request, response

  2. 该方法必须返回一个HttpResponse对象

    1. 默认返回的既是形参HttpResponse

    2. 也可以返回自己自定义的

  3. 顺序是按照中间件配置文件的顺序由下到上, 如果中间件没有定义该方法直接跳过执行下一个

知识点:如果第一个process_request方法就返回了HTTPResponse对象, 那么响应的时候是经过同级process_response返回

flask矿建中的中间件方法是返回的数据就必须经过所有的雷士与process_response方法

 

2.了解即可
        process_view(self, request, view_name, *args, **kwargs)
            路由匹配成功之后执行视图函数之前,会自动执行中间件里面的该方法
            顺序是按照配置文件中注册的中间件从上往下的顺序依次执行
            
        process_template_response(self, request, response)
            返回的HttpResponse对象有render属性的时候才会触发
            顺序是按照配置文件中注册了的中间件从下往上依次经过
            
        process_exception(self, exception)
            当视图函数中出现异常的情况下触发
            顺序是按照配置文件中注册了的中间件从下往上依次经过

csrf跨站请求伪造

钓鱼网站

内部本质
    我们在钓鱼网站的页面 针对对方账户 只给用户提供一个没有name属性的普通input框
    然后我们在内部隐藏一个已经写好name和value的input框

如何规避上述问题
    csrf跨站请求伪造校验
        网站在给用户返回一个具有提交数据功能页面的时候会给这个页面加一个唯一标识
        当这个页面朝后端发送post请求的时候 我的后端会先校验唯一标识,如果唯一标识不对直接拒绝(403 forbbiden)如果成功则正常执行

# form表单如何符合校验
<form action="" method="post">
    {% csrf_token %}
    <p>username:<input type="text" name="username"></p>
    <p>target_user:<input type="text" name="target_user"></p>
    <p>money:<input type="text" name="money"></p>
    <input type="submit">
</form>

# ajax如何符合校验
// 第一种 利用标签查找获取页面上的随机字符串
{#data:{"username":'jason','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()},#}
// 第二种 利用模版语法提供的快捷书写
{#data:{"username":'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},#}
// 第三种 通用方式直接拷贝js代码并应用到自己的html页面上即可
data:{"username":'jason'}

   

csrf相关装饰器

 

"""
1.网站整体都不校验csrf,就单单几个视图函数需要校验
2.网站整体都校验csrf,就单单几个视图函数不校验
"""
from django.views.decorators.csrf import csrf_protect,csrf_exempt
from django.utils.decorators import method_decorator
"""
csrf_protect  需要校验
    针对csrf_protect符合我们之前所学的装饰器的三种玩法
csrf_exempt   忽视校验
    针对csrf_exempt只能给dispatch方法加才有效
"""
# @csrf_exempt
# @csrf_protect
def transfer(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        target_user = request.POST.get('target_user')
        money = request.POST.get('money')
        print('%s给%s转了%s元'%(username,target_user,money))
    return render(request,'transfer.html')

 

from django.views import View

# @method_decorator(csrf_protect,name='post')  # 针对csrf_protect 第二种方式可以
# @method_decorator(csrf_exempt,name='post')  # 针对csrf_exempt 第二种方式不可以
@method_decorator(csrf_exempt,name='dispatch')
class MyCsrfToken(View):
    # @method_decorator(csrf_protect)  # 针对csrf_protect 第三种方式可以
    # @method_decorator(csrf_exempt)  # 针对csrf_exempt 第三种方式可以
    def dispatch(self, request, *args, **kwargs):
        return super(MyCsrfToken, self).dispatch(request,*args,**kwargs)

    def get(self,request):
        return HttpResponse('get')

    # @method_decorator(csrf_protect)  # 针对csrf_protect 第一种方式可以
    # @method_decorator(csrf_exempt)  # 针对csrf_exempt 第一种方式不可以
    def post(self,request):
        return HttpResponse('post')

importlib模块

可以将''xxx.yy''通过importlib.import_module()方法装换成form xxx import yy

最多只能到py文件名

 

重要思想

import settings
import importlib


def send_all(content):
    for path_str in settings.NOTIFY_LIST:  #'notify.email.Email'
        module_path,class_name = path_str.rsplit('.',maxsplit=1)
        # module_path = 'notify.email'  class_name = 'Email'
        # 1 利用字符串导入模块
        module = importlib.import_module(module_path)  # from notify import email
        # 2 利用反射获取类名
        cls = getattr(module,class_name)  # Email、QQ、Wechat
        # 3 生成类的对象
        obj = cls()
        # 4 利用鸭子类型直接调用send方法
        obj.send(content)

posted @   努力搬砖的zh  阅读(120)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示