Django基础篇:django操作cookie和session、CBV添加装饰器、django中间件、asrf跨站请求伪造
2022.5.24 django操作cookie和session,django中间件,asrf跨站请求伪造
- django操作cookie补充
- django操作session
- CBV添加装饰器的三种方式
- django中间件简介
- django中间件五个常见方法
- csrf跨站请求伪造
一、django操作cookie补充
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
# signed_cookie
set_signed_cookie(key,value,salt='加密盐')
set_signed_cookie(key,value,max_age=超时时间:默认是秒数)
expires:专门针对IE浏览器设置超时时间
eg:
res.set_cookie('name', 'jason')
res.set_signed_cookie('name', 'jason',salt='你好啊',max_age=3)
# delete_cookie
HttpResponse对象.delete_cookie(key)
eg:
def logout(request):
res = redirect('/login/')
res.delete_cookie('name')
return res
二、django操作session
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
# 设置
request.session['key'] = value # 可以设置多组
eg:
request.session['name1'] = '周二了还有三天周末了'
request.session['name2'] = '儿童节放不放假'
request.session['name3'] = '端午节放不放假'
# 获取
request.session.get('key') # 可以获取多组
eg:
res1 = request.session.get('name1')
res2 = request.session.get('name2')
res3 = request.session.get('name3')
print(res1, res2, res3)
# 周二了还有三天周末了 儿童节放不放假 端午节放不放假
print(request.session.session_key)
# 4wcog1llonkvyo5im7fcahuje9b87gl7
# django操作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失效策略。
"""
服务端保存用户相关状态信息,返回给客户端随机字符串;
针对保存,django需要一张表来处理 >>> 自带的django_session表
ps:django数据库迁移命令会产生一堆默认的表,其中就有一张django_session表;
"""
1.设置session:内部发生的事情
1.产生一个随机字符串
2.表中存储随机字符串与加密数据的对应关系
3.并将产生的随机字符串也给客户端发送一份并让其保存
sessionid:随机字符串
2.获取session:内部发送的事情
1.自动获取客户端请求中的随机字符串
2.自动去存储session数据的表中比对
3.如果比对成功自动获取并'解密处理'
ps:django默认的session失效时间是14天
# 针对session数据存储位置的五种方案
1.数据库存储
2.缓存存储
3.文件存储
4.缓存+数据库存储
5.动态加密
三、CBV添加装饰器的三种方式
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
'''需要借助于一个专门的装饰器模块'''
from django.utils.decorators import method_decorator
from django import views
# 方式1:直接在类中的某个方法上添加
class MyLoginView(views.View):
def get(self, request):
return HttpResponse("from CBV get view")
# 方式2:直接在类名上添加并指定参数
class MyLoginView(views.View):
def get(self, request):
return HttpResponse("from CBV get view")
# 方式3:重写dispatch方法并添加作用于类中所有的方法
就是将所有类方法都加上装饰器
class MyLoginView(views.View):
def dispatch(self, request, *args, **kwargs):
super().dispatch(request,*args,**kwargs)
四、django中间件
1、django中间件简介
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
# 回忆django请求生命周期流程图
是django的门户,自带七个中间件,每个都有各自对应的功能;
# 五个自定义方法
django不单有七个中间件并且每个都有很多功能和方法,除此之外django还支持自定义中间件并提供五个可以自定义的方法;
process_request
process_response
process_view
process_template_response
process_excepton
# django中间件的使用场景
只要是全局相关的功能都可以在中间件中编写;
eg:用户黑名单校验、用户访问频率校验、网站全局用户身份校验
2、django中间件五个常见方法
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
# 自定义中间件步骤
1.创建一个任意名称的文件夹
eg:mymiddleware
2.在该文件夹内创建一个任意名称的py文件
eg:mmymdd.py
3.在该py文件内编写中间件类
from django.utils.deprecation import MiddlewareMixin
class MyMdd1(MiddlewareMixin):...
class MyMdd2(MiddlewareMixin):...
4.配置文件中注册
MIDDLEWARE = [
'七个默认中间件', # 此处省略
# 注册自定义中间件
'app01.mymiddleware.mymdd.MyMdd1',
'app01.mymiddleware.mymdd.MyMdd2',
]
# 必须要掌握的方法
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方法:
# 视图函数
def ab_md(request):
print('视图函数:ab_md')
def render():
return HttpResponse('很奇葩')
res = HttpResponse("视图函数:ab_md")
res.render = render
return res
3.process_exception
视图函数执行过程中报错并在返回响应的时候会从下往上执行配置文件中注册了的中间件里面的process_exception
# 代码演示
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就是视图函数返回给客户端的数据
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 MyMdd1 process_view')
def process_template_response(self,request,response):
print('自定义中间件:from MyMdd1 process_template_response')
return response
def process_exception(self,request,exception):
print(exception)
print('自定义中间件:from MyMdd1 process_exception')
class MyMdd2(MiddlewareMixin):
def process_request(self, request):
print('自定义中间件:from MyMdd2 process_request')
def process_response(self, request, response):
print('自定义中间件:from MyMdd2 process_response')
# return HttpResponse('哈哈哈 中途调包喽')
return response # response就是视图函数返回给客户端的数据
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')
def process_template_response(self,request,response):
print('自定义中间件:from MyMdd2 process_template_response')
return response
def process_exception(self,request,exception):
print(exception)
print('自定义中间件:from MyMdd2 process_exception')
五、csrf跨站请求伪造
1、概念
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
# 举例
钓鱼网站:一个模仿正规网站的网址,诱骗用户在该网站上做本应该在正规网站上做的操作,从而获取到该用户在正规网站上的数据甚至是财产;
eg:假设我们需要登录网页完成转账操作
我们不小心登录到了钓鱼网站,填写了账户、密码、对方账户等信息;
点击转账之后我们账户的钱确实减少了,但是对方账户却变成了一个你从来不认识的人;
原理:将收款人的账号,提前写成犯罪分子的然后隐藏,暴露给用户一个没有name属性的标签写着玩;
# 简单模拟
开设两个django项目,模拟两个相同的页面,具体参考课上代码;
这样一些不法分子就可以通过这种方式窃取劳动人民的辛勤成果,因此我们要避免这种情况发生!
2、crf解决策略
主要原理是在页面添加一些标志用于后端的校验,如果接收到的请求页面没有这些标志,那么就无法访问;
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
"""针对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表单还是需要额外指定{% csrf_token %};
步骤:
(1)可以在static文件夹下创建一个js文件
(2)复制下面代码(js脚本处理代码)到此js文件下:
(3)在前端导入js文件
{% load static %}
<script src="{% static 'myjs.js' %}"></script>
js脚本处理代码:
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
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);
}
}
});
作业
复制代码
- 1
- 2
1.使用session编写完整的登录功能并添加装饰器完善
2.思考如何使用django中间件完成用户黑名单、权限等功能限制(后续课程讲RBAC)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了