cookie、session、CBV装饰器、中间件、csrf跨站请求伪造
cookie、session、CBV装饰器、中间件、csrf跨站请求伪造
昨日回顾—不足就努力
forms组件钩子函数
局部钩子:从通过了forms组件的第一层的字段数据筛选中拿出单个数据
def clean_字段名(self):
变量名 = self.cleaned_data.get('字段')
数据判断操作
return 变量名 # 拿了什么返还什么
全局钩子:从通过了forms组件的第一层的字段数据筛选中拿出全部数据
def clean(self):
变量名 = self.cleaned_data.get('字段')
变量名1 = self.cleaned_data.get('字段1')
数据判断操作
return self.cleaned_data # 返回全部
modelform组件
将forms组件与models结合,节省代码冗余
from django import forms
class MyModelForm(forms.ModelForm):
class Meta:
name = app.表
fields = '__all__'
obj.save() # 保存数据
cookie与session简介
# cookie
服务端让客户端保存的一些数据(主要是记录用户状态)
# session
服务端保存客户端用户相关数据(主要是记录用户状态)
ps:session的工作需要依赖于cookie
"""
token
session需要在服务端保存数据 IO有点多
token则不需要保存数据 是动态加密比对!!!
"""
django操作cookie
res = HttpResponse对象.set_cookie(key,value) # 设置cookie键值对
request.COOKIE.get(key) # 获取cookie值
return res
今日学习内容
作业讲解
def login_auth(func_name): # 登录认证装饰器
def inner(request, *args, **kwargs): # 闭包函数
# print(request.path)
# print(request.path_info)
# 1.获取用户没有登录之前想要访问的网址地址
target_path = request.get_full_path() # 获取路由
if request.COOKIES.get('name'): # 如果饼干中有键值对,证明已经登录过
res = func_name(request, *args, **kwargs) # 运行原来的函数接受返回值
return res # 返回HttpRespones类
else:
# 2.将用户想要访问的地址当做参数传给登录功能
return redirect(f'/login/?next={target_path}') # 返回登录页面并携带原本路由
return inner
def login(request):
if request.method == 'POST': # POST请求
name = request.POST.get("name") # 获取键值对
if name == 'jason': # 符合登录成功
# 获取用户登录之前想要访问的地址
next_path = request.GET.get('next')
'''注意 用户也有可能直接访问的登录页面 没有想要访问的其他页面'''
if next_path:
res = redirect(next_path) # 跳转到之前想要访问的界面
else:
res = redirect('/home/') # 默认登录之后跳转的界面
res.set_cookie('name', 'jason') # 携带饼干
return res
return render(request, 'login.html') # 返回登录页面
django操作cookie补充
set_signed_cookie(key,value,salt='加密盐') # 饼干加盐处理
set_signed_cookie(key,value,max_age=超时时间:默认是秒数) # 保存饼干的时间
expires:专门针对IE浏览器设置超时时间 # 老古董
HttpResponse对象.delete_cookie(key) # 删除饼干键值对
django操作seesion
# 设置
request.session['key'] = value # 可以设置多组
# 获取
request.session.get('key') # 可以获取多组
"""服务端保存用户相关状态信息 返回给客户端随机字符
串针对保存 django需要一张表来处理 >>> 自带的django_session表
ps:django数据库迁移命令会产生一堆默认的表 其中就有一张django_session表"""
1.设置session内部流程
1.1:产生一个随机字符串:sessionid
1.2:表中存储sessionid与加密数据的对应关系
1.3:并将产生的sessionid也给客户端发送一份并让其保存
2.获取session内部发送的事情
2.1:自动获取客户端请求中的sessionid
2.2:去存储了session数据的地方进行比对
2.3:比对成功自动获取对应数据并解密处理
session补充
request.session.session_key # 获取产生的随机字符串
request.session.delete() # 只删客户端
request.session.flush() # 服务端 客户端都删
request.session.set_expiry(value) # 设置超时时间
* 如果value是个整数,session会在些秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。(14day)
针对session数据的存储位置 有五种方案
1.数据库存储
2.缓存存储
3.文件存储
4.缓存+数据库存储
5.动态加密
CBV添加装饰器
from django.utils.decorators import method_decorator # 导入装饰器模块
第一种:直接在类中的某个方式上添加装饰器
class MyLogView(views.View): # 继承视图类
@method_decorator(login_auth) # 添加装饰器
def get(self, request):
return HttpResponse("from CBV get view")
第二种:直接在类名上添加并指定
@method_decorator(login_auth, name='get') # 添加装饰器,并指定方法
class MyLoginView(views.View):
def get(self, request):
return HttpResponse("from CBV get view")
# 方式3:重写dispatch方法并添加作用于类中所有的方法
class MyLoginView(views.View):
@method_decorator(login_auth)
def dispatch(self, request, *args, **kwargs): # 根据之前解析CBV源码,最后都会走到dispatch函数
super().dispatch(request,*args,**kwargs)
django中间件
之前我们在学习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',
]
中间件们从上至下对Request(请求消息)来接,从下至上对Response(返回消息)去送:

自定义中间件
既然中间件是一种钩子框架,那就好理解了:会在系统处于某种状态时自动调用。而这种系统状态就是django接收到请求request时的状态。中间件作用就是用于处理用户请求、产生响应内容。其实,中间件就是Request到views、views到Response的一段处理过程。这个处理过程依赖于settings中激活的顺序:
使用方式:
1.创建一个任意名称的文件夹
2.在该文件夹内创建一个任意名称的py文件
3.在该py文件内编写中间件类
4.配置文件字典中添加
重点:1.process_request 2.process_response
1.process_request
请求来的时候会从上往下依次执行配置文件中注册了的中间件里面的process_request方法 如果没有则直接跳过
如果该方法自己返回了HttpResponse对象,那么请求不再继续往后直接返回相应的数据
2.process_response
响应走的时候会从下往上依次执行配置文件中注册了的中间件里面的process_response方法 如果没有则直接跳过
如果该方法自己返回了HttpResponse对象,那么响应会替换成该HttpResponse对象数据 而不再是视图函数想要返回给客户端的数据
"""如果process_request返回了HttpResponse对象 那么会从当前位置从下往上执行每一个process_response"""
了解:
1.process_view
路由匹配成功之后执行视图之前从上往下执行配置文件中注册了的中间件里面的process_view方法
2.process_template_response
视图函数执行完毕之后返回的对象中含有render属性对应一个render方法
则会从下往上执行配置文件中注册了的中间件里面的process_template_response方法
3.process_exception
视图函数执行过程中报错并在返回响应的时候会从下往上执行配置文件中注册了的中间件里面的process_exception
csrf跨站请求伪造
我们偶尔会遇到那种非法的,但是但是表面页面与正规网页一样,用户使用后这种网页后,会窃取信息数据甚至财产;这种就是钓鱼网站
逻辑其实非常简单:窃取正规页面的布局;输入信息的接口不是返回到正规网站后台上,而是返回到钓鱼网站的后台上
那么用户在使用的时候,姑且不考虑网页拦截这些问题,用户以为自己登录的是正规网页,实际将自己的所有隐私暴露了,甚至会将钱财直接赚到不法分子手上
csrf解决策略
"""针对csrf相关的校验有很多种方式 django只是提供了一些而已"""
# form表单
<form action="" method="post">
{% csrf_token %}
<p>当前账户:<input type="text" name="current_user"></p>
<p>目标账户:<input type="text" name="target_user"></p>
<p>转账金额:<input type="text" name="money"></p>
<input type="submit">
</form>
# ajax请求
1.方式1:页面任意位置先写{% csrf_token %} 之后获取数据 'csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()
2.方式2:模板语法直接获取
'csrfmiddlewaretoken':{{ csrf_token }}
"""通用解决方案:js脚本自动处理"""
也只能适用于ajax提交 form表单还是需要额外指定
作业
1.已做
2.思考🤔

浙公网安备 33010602011771号