django的session原理流程,自定义中间件,csrf跨站请求伪造

本文介绍了Django的session工作原理,详细讲解了自定义中间件的实现,包括process_request、process_response、process_view和process_exception四个方法。同时,深入探讨了CSRF跨站请求伪造问题,并通过代码演示了防范CSRF攻击的方法。
摘要由CSDN通过智能技术生成

一.昨日回顾

1 django中cookie的使用
	-增 obj.set_cookie(key,value,max_age)
	-删 obj.delete_cookie(key)
	-查 request.COOKIE.get(key)
	-改 obj.set_cookie(key,value,max_age)
2 django中session的使用(迁移数据库)
	-增 request.session['key']=value
	-del request.session['key']
	-全部删除 request.session.flush():cookie和数据库都删除,request.session.delete():只删数据库
	-查 request.session['key']
	-改 request.session['key']=value
	
	-超时时间

3 cbv加装饰器
	-第一种:加在类上
	fromdjango.utils.decorators import method_decorator
	@method_decorator(login_auth,name='get')
	class UserList(views.View):
		pass
	-第二种:加在方法上
	from django.utils.decorators import method_decorator
	class UserList(views.View):
		@method_decorator(login_auth)
		def get(self):
			pass

二.今日内容

1.django的session原理流程

在这里插入图片描述

2.自定义中间件

1 自定义步骤:
	-写一个类,继承MiddlewareMixin
	-里面写方法process_request(请求来了,一定会触发它的执行)
	-在setting中配置(注意,放在前和放在后)
	MIDDLEWARE = [
		...
		'app01.mymiddle.MyMiddleware1',
		...
	]

3.process_request,process_response,process_view,process_exception

1 process_request(request对象)
2 process_response(request对象,response对象)
3 多个中间件,执行顺序是什么?
	-请求来的时候,从上往下执行:process_request
	-请求走的时候,从下往上执行:process_response
4 process_request可以干什么?
	-写一个中间件,不管前端用什么编码,在request.data中都有post的数据
	-频率限制(限制某个ip地址,一分钟只能访问5)
	-登录认证(只要没登录,重定向到login路径)
	-记录用户访问日志(ip,时间,访问路径)

5 process_response可以干什么?内部有response对象
	-统一给所有(某几个路径)加cookie
	-统一给所有(某几个路径)加响应头

6 process_view路由匹配成功和视图函数执行之前执行(callback就是视图函数)
	def process_view(self, request, callback, callback_args, callback_kwargs):
	# print(callback)
            # print(callback_args)
            # print(callback_kwargs)
            #
            res=callback(request)
            #
            print("中间件1的process_view")
            return res

7 process_exception 视图函数出错,会执行它(全局异常捕获)(记录日志,哪个ip地址,访问哪个路径,出的错)
# 全局异常捕获,返回4开头的
def process_exception(self,request,exception):
	print(exception)
	return render(request,'error.html')

如果当请求到达请求2的时候直接不符合条件返回,即return HttpResponse(“ok”),程序将把请求直接发给中间件2返回,然后依次返回到请求者,结果如下:

在这里插入图片描述

process_view
在这里插入图片描述

process_exception
当views出现错误时:
在这里插入图片描述

4.CSRF_TOKEN跨站请求伪造

1 跨站请求伪造
2 代码演示
3 django解决了csrf攻击,中间件:
django.middleware.csrf.CsrfViewMiddleware

4 后期中间件不能注释,每次发送post请求,都需要携带csrf_token随机字符串
	-form表单提交
		-在form表单中{% csrf_token %}
	-ajax提交(如何携带)
	方式一:放到data中
	方式一 依然要先书写{% csrf_token %},再通过默认储存标识码的标签获取标识码
	$.ajax({
            url: '/csrf_test/',
            method: 'post',
            data: {'name': $('[name="name"]').val(),
                'password': $('[name="password"]').val(),
                'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()
            },
            success: function (data) {
                console.log('成功了')
                console.log(data)

            },
            error: function (data) {
                console.log('xxxxx')
                console.log(data)

            }
        })
        方式二:放到data中
        方式二 利用模板语法获取标识码
        'csrfmiddlewaretoken':'{{ csrf_token }}'
        方式三:放到头中
        方式三 通过导入js模块,声明ajax的post请求默认携带标识码
        	headers:{'X-CSRFToken':'{{csrf_token}}'},

# jquery.cookie.js
	-再浏览器中对cookie进行增,,,-前后端分离(js操作cookie)


# 全局使用,局部禁csrf
	-在视图函数上加装饰器
    from django.views.decorators.csrf import csrf_exempt,csrf_protect
# 全局启用,局部禁用(中间件不能注释,这个视图函数,已经没有csrf校验了)
# @csrf_exempt
# def csrf_test(request):
#     if request.method=='GET':
#         return render(request,'csrf_test.html')
#     else:
#         name=request.POST.get('name')
#         password=request.POST.get('password')
#         print(name)
#         print(password)
#         return HttpResponse('登录成功')

# 全局禁用,局部使用csrf
@csrf_protect
def csrf_test(request):
    if request.method=='GET':
        return render(request,'csrf_test.html')
    else:
        name=request.POST.get('name')
        password=request.POST.get('password')
        print(name)
        print(password)
        return HttpResponse('登录成功')



# 古怪的使用方式,在urls.py中
path('csrf_test/', csrf_exempt(views.csrf_test))
跨站请求伪造代码演示

views.py

def login_auth(func):
    def inner(request, *args, **kwargs):
        # 登录校验
        name = request.session.get('name')
        if name:
            res = func(request, *args, **kwargs)
            return res
        else:
            path = request.get_full_path()
            return redirect('/login/?returnUrl=%s' % path)

    return inner


### session版登录
def login(request):
    if request.method == 'GET':

        return render(request, 'login.html')
    else:
        name = request.POST.get('name')
        password = request.POST.get('password')
        if name == 'lqz' and password == '123':
            # 写入session
            # 登录成功,重定向
            request.session['name']=name
            path = request.GET.get('returnUrl')
            if path:
                obj = redirect(path)
            else:
                obj = redirect('/index/')

            return obj
        else:
            return HttpResponse('用户名或密码错误')

@login_auth
def index(request):
    return render(request,'index.html')


@login_auth
def transfer(request):
    # /transfer/?from=lqz&to=egon&total=100
    f=request.GET.get('from')
    t=request.GET.get('to')
    total=request.GET.get('total')
    print('转账成功')
    return HttpResponse('转账成功')

def hack(request):
	return render(request,'hack.html')

urls.py

url(r'^$', views.index),
    url(r'^login/', views.login),
    url(r'^transfer/', views.transfer),
    url(r'^hack/', views.hack),

login.html

<body>
<form action="" method="post">
    <p>用户名: <input type="text" name="name"></p>
    <p>密码: <input type="password" name="password"></p>
    <p><input type="submit" value="提交"></p>
</form>
</body>

index.html

<body>
<a href="/transfer/?from=lqz&to=egon&total=100">点我给egon转100块钱</a>

</body>

hack.html

<body>
<a href="http:127.0.0.1:8000/transfer/?from=lqz&to=egon&total=100">点我了解更多</a>

</body>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值