中间件,csrf

目录

-中间件

--介绍

--自定义中间件

---方法

---process_request(self, request)

---process_response(self, request, response)

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

---process_template_response(self, request, response)

---process_exception(self, request, exception)

-CSRF校验

--简介

--form表单符合csrf校验

--Ajax符合csrf校验

--csrf装饰器添加方法

---CBV方式添加csrf装饰器


-中间件

--介绍

中间件是Django的门卫(Django生命周期流程图),用于在全局范围内改变Django的输入和输出

官方介绍是:中间件是一个用来处理Django的请求和响应的框架级别的钩子,是一个轻量、低级别的插件系统,每个中间件负责一些特定的功能

1、请求来的时候需要经过中间件的层层逐次(正向)检查才能进入Django后端

2、请求走的时候需要经过中间件的层层逐次(反向)检查才能返回给浏览器

Django自带7个中间件,新建一个Django项目时,在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',
]

MIDDLEWARE配置是一个有序列表, 列表中是一个个字符串,但其实是一个个类的导入

eg:

        from django.middleware.security import SecurityMiddleware

--自定义中间件

除了新建项目时Django自带的7个中间件,Django还允许我们自定义中间件

通过查看初始的7个中间件的源码,发现每个类下都有共同的5个方法:

process_request(self,request)
process_view(self, request, view_func, view_args, view_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
process_response(self, request, response)

其中process_request和process_response用的最多且最为重要

---方法

# 自定义中间件的方法步骤
1、在项目或应用下创建一个任意名称的目录
2、在该目录下创建一个.py文件
3、在该py文件内书写类(必须继承MiddlewareMixin),然后在该类下定义那5个方法
    from django.utils.deprecation import MiddlewareMixin
4、将类的路径以字符串形式注册到settings.py的MIDDLEWARE列表中

示例:

# 自定义一个中间件,无论form表单还是Ajax提交过来的json格式数据,统一存放在process_request的request.data中

from django.utils.deprecation import MiddlewareMixin
import json

class MyJsonMiddleware(MiddlewareMixin):
    def process_request(self, request):
        try:
            request.data = json.loads(request.body)
        except Exception as e:
            requset.data = request.POST

---process_request(self, request)

1、参数request和视图函数中的request是一样的

2、请求来的时候需要执行每个中间件的process_request方法,执行顺序从上往下

3、如果某个中间件中没有定义process_request方法,直接跳过执行下一个

4、如果process_request方法返回了HttpResponse对象(3个),那么请求不再继续往后执行,而是原路返回

5、中间件的process_request方法是在执行视图函数前执行的

'''app01下的mymiddleware目录下的mymiddlewaretest.py中'''
from django.utils.deprecation import MiddlewareMixin

class MyMiddleware1(MiddlewareMixin):
    def process_request(self, request):
        print("MyMiddleware1里面的process_request")

class MyMiddleware2(MiddlewareMixin):
    def process_request(self, request):
        print("MyMiddleware2里面的 process_request")

'''在settings.py中的MIDDLEWARE中注册上述两个中间件'''
MIDDLEWARE = [
    .......
    'app01.mymiddleware.mymiddlewaretest.MyMiddleware1',  # 自定义中间件1
    'app01.mymiddleware.mymiddlewaretest.MyMiddleware2'   # 自定义中间件2
]

'''访问一个视图,终端打印如下'''
MyMiddleware1里面的process_request
MyMiddleware2里面的 process_request
app01中的test视图

---process_response(self, request, response)

1、响应走的时候需要经过并执行每个中间件里的process_response方法

response参数是返回的HttpResponse对象

2、该方法必须返回一个HttpResponse对象,默认返回对象就是response,也可以返回自己的

3、执行顺序是从下往上,若某个中间件没有该方法则跳过它执行下一个

如果当某个中间件的process_request方法有返回对象直接返回后,就会走同级别的process_response返回了,而不会走下面的中间件了

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

1、在执行完process_request方法后执行视图函数前,会执行该方法

2、该方法有4个参数:

        request是HttpResponse对象

        view_func是Django即将使用的视图函数

        view_args是传递给视图的位置参数的列表

        view_kwargs是传递给视图的关键字参数的字典

3、执行顺序是从上往下顺序执行。返回None时,Django将继续处理这个请求,继续执行其它中间件的process_view方法;返回HttpResponse对象时,将不再执行视图函数,而是在同级别掉头执行process_response方法

---process_template_response(self, request, response)

返回的HttpResponse对象有render属性时才会触发,视图函数执行完后立即执行

顺序是从下往上

---process_exception(self, request, exception)

当视图函数出现异常的情况下触发。若返回None,则将异常交给下一个中间件的process_exception方法来处理;若返回HttpResponse对象,则从同级开始往上执行process_response方法,并返回给浏览器。

执行顺序从下往上



-CSRF校验

--简介

csrf(Cross-site request forgery)跨站请求伪造:网站在给用户返回一个具有提交数据功能的页面的时候会给这个页面加一个唯一标识。当这个页面朝后端发送post请求时,后端会先校验这个唯一标识,如果不对则直接拒绝(显示403 Forbidden页面),成功才正常执行后续

之前已经接触过一个csrf相关的中间件了'django.middleware.csrf.CsrfViewMiddleware'

我们一开始让把它注释掉,再提交post请求的时候,就不会被forbidden了

现在使用csrf就可以不再注释这个中间件了

--form表单符合csrf校验

<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>

只需要加上{% csrf_token %}后,每次请求后端都会发一个唯一标识,体现在页面上就是多了一个<input type="hidden" name="csrfmiddlewaretoken" value="RbzvDpgCyvKjBSMnMuZiTXfyGcYBVlU3MoI5P6uYtG07kob0W1gXU8unS7AI3HDM">且每次访问value=""都不一样

--Ajax符合csrf校验

三种方式:

{# 引入通用方法js文件(第三种方式) #}
<script src="{% static  'js/mysetup.js'%}"></script>
{# ajax请求代码 #}
<script>
    $('#submit').click(function (){
        $.ajax({
            url:'',
            type:'post',
            {#// 第一种 利用标签查找到该随机字符串 data的键必须是csrfmiddlewaretoken#}
            {#data:{'name':'weer','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()},#}
            {#// 第二种 利用模板语法快捷书写#}
            {#data:{'username':'weer', 'csrfmiddlewaretoken': '{{ csrf_token }}'},#}
            // 第三种 通用方式 引入官方js代码到html页面 然后啥也不写
            success:function (args){

            }
        })
    })
</script>

--csrf装饰器添加方法

现有如下需求:

        1.网站整体都不校验csrf,就单单几个视图函数要校验

        2.网站整体都校验csrf,就单单几个视图函数不校验

要实现上述需求,需要用到装饰器

from django.views.decorators.csrf import csrf_protect, csrf_exempt

csrf_protect:      需要校验
csrf_exempt:       忽略校验

针对需求1:

        注释掉那个csrf中间件,然后对要csrf校验的视图函数上加@csrf_protect

针对需求2:

        打开那个csrf中间件,对不csrf校验的视图函数上加@csrf_exempt

---CBV方式添加csrf装饰器

from django.utils import method_decorator
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')  # 针对csrf_exempt,这种可以(四)
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')

总结:csrf_protect三种方式都行;csrf_exempt只有第三种方式或“四”可行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weer-wmq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值