cookie与session、django操作cookie、django操作session、django中间件
cookie与session、django操作cookie、django操作session、django中间件
一、cookie与session简介
什么是cookie:Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息。
cookie工作原理:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上Cookie,这样服务器就能通过Cookie的内容来判断这个是“谁”了。
什么是session:Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。
session工作原理:客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。每个用户访问服务器都会建立一个session,那服务器是怎么标识用户的唯一身份呢?事实上,用户 与服务器建立连接的同时,服务器会自动为其分配一个SessionId。
cookie和session的区别:
- 数据存储位置:cookie数据存放在客户的浏览器上,session数据放在服务器上。
- 安全性:cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。
- 服务器性能:session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。
- 信息重要程度:可以考虑将登陆信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中。
HTTP四大特性:
- 基于请求响应
- 基于TCP/IP作用于应用层之上的协议
- 无状态:服务端无法识别客户端的状态
- 无连接
Cookie:
保存在客户端上跟用户信息(状态)相关的数据
Session:
保存在服务端上跟用户信息(状态)相关的数据
PS:Session的工作需要依赖于Cookie,就算是目前能够识别用户身份的网址也都需要使用Cookie(客户端浏览器也有权拒绝保存Cookie)
二、django操作cookie
1、获取cookie
request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
参数:
default:默认值
salt:加密盐
max_age:后台控制过期时间
2、设置cookie
'''
设置cookie:set_cookie()
rep = HttpResponse(...)
rep = render(request, ...)
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密盐', max_age=None, ...)
'''
如果想要客户端浏览器保存cookie需要HttpResponse对象调用方法
return HttpResponse()
return render()
return redirect()
return JsonRepsonse()
设置cookie需要变形
obj = HttpResponse() # 就是为了可以调用cookie的方法
obj.操作cookie的方法
return obj
obj = render() # 就是为了可以调用cookie的方法
obj.操作cookie的方法
return obj
obj = redirect() # 就是为了可以调用cookie的方法
obj.操作cookie的方法
return obj
obj = JsonRepsonse() # 就是为了可以调用cookie的方法
obj.操作cookie的方法
return obj
eg:
def set_cookie(request):
obj = HttpResponse('中秋节快乐,我miss你')
# 让浏览器保存cookie数据
obj.set_cookie('name', 'jimin')
return obj
参数 | 描述 |
---|---|
key | cookie的key |
value='' | cookie的value |
max_age=None | 最长生命周期,超时时间,单位是秒 |
expires=None | 过期时间,跟max_age类似,只不过这个参数需要传递一个具体的日期,如datetime或者是符合日期格式的字符串。注意,如果同时设置了expires和max_age,那么将会使用expires的值作为过期日期 |
path='/' | Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问 |
domain=None | 针对哪个域名有效。默认是针对主域名下都有效,如果只要针对某个子域名才有效,可以设置这个属性 |
secure=False | 是否是安全的,如果设置为True,那么只能在https协议下才可用 |
httponly=False | 默认是False,只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖) |
3、删除cookie
def logout(request):
res = redirect("/login/")
res.delete_cookie("name") # 删除用户浏览器上之前设置的name值
return res
4、补充
request.path # 获取当前url,但不含参数
request.path_info # 获取当前url,但不含参数
request.get_full_path() # 获取当前url,包含参数
请求一个http://127.0.0.1:8000/index/?name=jimin&pwd=1013
request.path 返回 /index/
request.path_info 返回 /index/
request.get_full_path() 返回 /index/?name=jimin&pwd=1013
cookie指定用户登录
1)登录设置cookie
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'jimin' and password == '1013':
obj = HttpResponse('登录成功')
obj.set_cookie('name', 'jimin_moon')
return obj
return render(request, 'login.html')
def home(request):
if request.COOKIES.get('name'):
return HttpResponse('from home,只有登录的用户才可以查看:jimin,you are the moon god')
return redirect('/login/')
2)多个视图函数都需要校验用户是否登录>>>>: 装饰器
def login_auth(func_name):
def inner(request, *args, **kwargs):
if request.COOKIES.get('name'):
res = func_name(request, *args, **kwargs)
return res
else:
return redirect('/login/')
return inner
@login_auth
def home(request):
return HttpResponse('from home,只有登录的用户才可以查看:jimin,you are the moon god')
3)如何记住用户登录之前想要访问的页面 用户登录成功之后自动跳转
场景1:用户访问了其他需要登录才可以访问的页面 如何跳转>>>:想要访问的页面
获取路由后缀,然后根据后缀是否有值跳转到指定页面
target_path = request.GET.get('next')
if target_path:
obj = redirect(target_path) # 如果有值则跳转到指定页面
场景2:用户直接访问的登录页面 如何跳转>>>:网址首页
obj = redirect('/home/') # 如果没有值则跳转到首页
完整代码:
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def set_cookie(request):
obj = HttpResponse('中秋节快乐,我miss你')
# 让浏览器保存cookie数据
obj.set_cookie('name', 'jimin')
return obj
def login_auth(func_name):
def inner(request, *args, **kwargs):
if request.COOKIES.get('name'):
res = func_name(request, *args, **kwargs)
return res
else:
target_path = request.path_info
return redirect(f'/login/?next={target_path}')
return inner
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'jimin' and password == '1013':
target_path = request.GET.get('next')
if target_path:
obj = redirect(target_path) # 如果有值则跳转到指定页面
else:
obj = redirect('/home/') # 如果没有值则跳转到首页
obj.set_cookie('name', 'jimin_moon', max_age=3) # 设置三秒后登录是失效
return obj
return render(request, 'login.html')
@login_auth
def home(request):
# if request.COOKIES.get('name'):
return HttpResponse('from home,只有登录的用户才可以查看:jimin,you are the moon god')
# return redirect('/login/')
@login_auth
def index(request):
# if request.COOKIES.get('name'):
return HttpResponse('from index,只有登录的用户才可以查看:jimin,I miss you')
# return redirect('/login/')
三、django操作session
请求来之后服务端产生随机字符串并发送给客户端保存,服务端存储随机字符串与用户信息的对应关系,之后客户端携带随机字符串,服务自动校验。
1.django默认的session失效时间为14天
2.客户端接收到键值对,键默认是sessionid值是加密的随机字符串(令牌)
request.session['name'] = 'jimin'
1)django自动产生一个随机字符串返回给客户端(对name加密)
2)往django_session创建数据(对jason加密)
request.session.get('name')
1)自动从请求中获取sessionid对应的随机字符串
2)拿着随机字符串去django_session中匹配数据
3)如果匹配上还会自动解密数据并展示
session的存储位置有5种模式:
1)数据库
2)缓存数据库
3)文件
4)缓存+数据库
5)加密
1、获取、设置、删除Session中数据
request.session['name']
request.session.get('name',None)
request.session['name'] = 123 # 设置name的值
request.session.setdefault('name',123) # 存在则不设置
del request.session['name'] # 删除
2、session流程解析

3、session其它操作
1)删除当前回话所有session数据
request.session.delete() # 只删浏览器的session数据
2)删除当前回话数据并删除会话的cookie
request.session.flush() # 服务端和客户端的session数据都删除
3)设置会话session和cookie的超时时间
request.session.set_expiry(value)
* 如果value是整数,session会在秒数后失效
* 如果value是datatime或timedelta(时间差值),session就会在这个时间后失效
* 如果value是0,用户关闭浏览器session就会消失
* 如果value是None,session会依赖全局session失效策略(默认14天)
四、django中间件
中间件是一个用来处理django的请求和响应的框架级别的钩子,它是一个轻量、低级别的插件系统,用于在全局范围内改变django的输入和输出。每个组件都负责做一些特定的功能。由于其影响的是全局,所以需要谨慎使用,使用不当影响性能。说直白点,在视图函数执行之前和执行之后都可以做一些额外的操作,本质上就是一个自定义类,类中定义了几个方法,django框架会在请求的特定时间去执行这些方法。
- django中间件类似于django的门户,所有的请求来和响应走都必须经过中间件
- django默认自带七个中间件,每个中间件都有各自负责的功能
# settings.py文件中的配置
'''MIDDLEWARE配置项是一个列表,列表是‘有序的’,列表中是一个个字符串其实是一个个类也就是一个个中间件'''
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',
]
-
django支持自定义中间件,可以自定义无限个
-
django中间件使用场景:
- 全局用户身份校验
- 全局用户黑名单校验
- 全局用户访问频率校验
-
django自定义中间件的五个方法
- process_request(self,request)
- process_response(self, request, response)
- process_view(self, request, view_func, view_args, view_kwargs)
- process_template_response(self, request, exception)
- process_exception(self, request, exception)
1.process_request
1)请求来的时候会按照配置文件中注册了的中间件,从上往下执行每个一个中间件里面的process_request方法,如果没有则直接跳过。 中间件的process_request方法是在执行视图函数之前执行的; 当配置多个中间件时,会按照MIDDLEWARE中的注册顺序也就是列表的索引值从前到后依次执行; 不同中间件之间传递的request都是同一个对象。
2)该方法如果返回了HttpResponse对象,那么请求不会再往后执行,原路返回
2.process_response
1)响应走的时候会按照配置文件中注册了的中间件从下往上一次执行每一个中间件里面的process_response方法,没有则直接跳过 2)该方法有两个形参request和response,并且默认情况下应该返回response 3)该方法也可以自己返回HttpResponse对象,相当于狸猫换太子(将原来的response对象换成HttpResponse对象) 多个中间件中的process_response方法是按照MIDDLEWARE中的注册顺序倒序执行的; 定义process_response方法时,必须给方法传入两个形参,request和response。response是视图函数返回的HttpResponse对象(也就是说这是Django后台处理完之后给出一个的一个具体的视图)。该方法的返回值(必须要有返回值)也必须是HttpResponse对象。如果不返回response而返回其他对象,则浏览器不会拿到Django后台给他的视图,而是我的中间件中返回的对象。
PS:如果请求过程中process_request方法直接返回了HttpResponse对象那么会原地执行同级别process_response方法返回(flask则不同)
3.process_view
当理由匹配成功之后,执行视图函数之前自动触发 应该返回None或一个HttpResponse对象。 如果返回None,Django将继续处理这个请求,执行任何其他中间件的process_view方法,然后在执行相应的视图。 如果它返回一个HttpResponse对象,那么将不会执行Django的视图函数,而是直接在中间件中掉头,倒叙执行一个个process_response方法,最后返回给浏览器。
4.process_excption
当视图函数报错之后执行视图函数之前自动触发。 该方法两个参数:一个HttpRequest对象,一个exception是视图函数异常产生的Exception对象。 这个方法只有在视图函数中出现异常了才执行,它返回的值可以是一个None也可以是一个HttpResponse对象。
5.process_template_response
当视图函数返回的数据对象含有render属性对应render函数才会触发。 process_template_response是在视图函数执行完成后立即执行,但是它有一个前提条件,那就是视图函数返回的对象有一个render()方法(或者表明该对象是一个TemplateResponse对象或等价方法)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)