session+CBV装饰器+中间件+csrf
作者:互联网
django操作session
服务端保存用户相关状态信息,返回给客户端随机字符串,针对保存 django需要一张表来处理:django_session
表,即django数据库迁移命令会产生一堆默认的表,其中就有一张django_session
表。
django默认的session失效时间是14天。
设置
request.session['key'] = value # 可以设置多组
'设置session内部发生的事情'
1.产生一个随机字符串
2.表中存储随机字符串与加密数据的对应关系
3.并将产生的随机字符串也给客户端发送一份并让其保存,sessionid:随机字符串
获取
request.session.get('key') # 可以获取多组
'获取session内部发送的事情'
1.自动获取客户端请求中的随机字符串
2.自动去存储session数据的表中比对
3.如果比对成功自动获取并'解密处理'
补充
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失效策略。
针对session数据的存储位置 有五种方案
1.数据库存储
2.缓存存储
3.文件存储
4.缓存+数据库存储
5.动态加密
CBV添加装饰器
需要借助于一个专门的装饰器模块
from django.utils.decorators import method_decorator
直接在类中的某个方法上添加
class MyLoginView(views.View):
@method_decorator(login_auth) # 参数为装饰函数名
def get(self, request):
return HttpResponse("from CBV get view")
直接在类名上添加并指定
@method_decorator(login_auth, name='get') # (装饰函数名, name='被装饰方法名')
class MyLoginView(views.View):
def get(self, request):
return HttpResponse("from CBV get view")
重写dispatch方法并添加装饰器(作用于类中所有的方法)
class MyLoginView(views.View):
@method_decorator(login_auth)
def dispatch(self, request, *args, **kwargs):
super().dispatch(request,*args,**kwargs)
中间件
中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。
但是由于其影响的是全局,所以需要谨慎使用,使用不当会影响性能。
说的直白一点中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作,它本质上就是一个自定义类,类中定义了几个方法,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',
]
自定义中间件
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)
1.创建一个任意名称的文件夹
2.在该文件夹内创建一个任意名称的py文件
3.在该py文件内编写中间件类
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,redirect,render
class MyMdd1(MiddlewareMixin):
def process_request(self, request):
print('自定义中间件:from MyMdd1 process_request')
# return HttpResponse('from MyMdd1 process_request')
def process_response(self, request, response):
print('自定义中间件:from MyMdd1 process_response')
return response # response就是视图函数返回给客户端的数据
4.配置文件中注册
MIDDLEWARE = [
# 注册自定义中间件
'app01.mymiddleware.mymdd.MyMdd1',
'app01.mymiddleware.mymdd.MyMdd2',
]
掌握的方法
- process_request
def process_request(self, request):
print('自定义中间件:from MyMdd1 process_request')
return HttpResponse('from MyMdd1 process_request')
1.请求来的时候会从上往下依次执行配置文件中注册了的中间件里面的process_request方法,如果没有则直接跳过
2.如果该方法自己返回了HttpResponse对象,那么请求不再继续往后直接返回相应的数据
- process_response
def process_response(self, request, response):
print('自定义中间件:from MyMdd1 process_response')
return response # response就是视图函数返回给客户端的数据
1.响应走的时候会从下往上依次执行配置文件中注册了的中间件里面的process_response方法,如果没有则直接跳过
2.如果该方法自己返回了HttpResponse对象,那么响应会替换成该HttpResponse对象数据,而不再是视图函数想要返回给客户端的数据
PS:如果process_request返回了HttpResponse对象,那么会从当前位置从下往上执行每一个process_response。
了解的方法
- process_view
def process_view(self,request,view_func, view_args, view_kwargs):
# print('view_func',view_func) # 即将要执行的视图函数名
# print('view_args',view_args) # 传给视图函数的位置参数
# print('view_kwargs',view_kwargs) # 传给视图函数的关键字参数
print('自定义中间件:from MyMdd2 process_view')
路由匹配成功之后执行视图函数之前从上往下执行配置文件中注册了的中间件里面的process_view方法
- process_template_response
def process_template_response(self,request,response):
print('自定义中间件:from MyMdd2 process_template_response')
return response
视图函数执行完毕之后返回的对象中含有render属性对应一个render方法,则会从下往上执行配置文件中注册了的中间件里面的process_template_response方法
- process_exception
def process_exception(self,request,exception):
print(exception)
print('自定义中间件:from MyMdd2 process_exception')
视图函数执行过程中报错并在返回响应的时候会从下往上执行配置文件中注册了的中间件里面的process_exception
csrf(跨站请求伪造)
钓鱼网站:一个模仿正规网站的网址 诱骗用户在该网站上做本应该在正规网站上做的操作,从而获取到该用户在正规网站上的数据甚至是财产
eg:假设我们需要登录网页完成转账操作
我们不小心登录到了钓鱼网站 填写了账户 密码 对方账户等信息
点击转账之后我们账户的钱确实减少了 但是对方账户却变成了一个你从来不认识的人
原理:将收款人的账号 提前写成犯罪分子的然后隐藏 暴露给用户一个没有name属性的标签写着玩
解决策略
针对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>
会在HTML页面自动产生一个input标签,用于校验。submit提交的时候会带上这个生成的input里的value值,然后会和之前后端返回的页面里的value进行比对,如果正确,这个提交请求就让它过,如果不正确就步让请求通过。
<input type="hidden" name="csrfmiddlewaretoken" value="iQOCyIe4ETIYSfVSji3SqJlt3XeEJs8pujSuiNG5aKHrKZbfzusiLQ5erZHnfpk8"> # value随机
ajax请求
方式1:页面任意位置先写{% csrf_token %} 之后获取数据
'csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()
方式2:模板语法直接获取
'csrfmiddlewaretoken':{{ csrf_token }}
方式3:js脚本自动处理(适用于ajax)
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);
}
}
});
标签:process,request,中间件,session,CBV,response,view 来源: https://www.cnblogs.com/RainKz/p/16307779.html