cookie和session
cookie和session简介
由http引入
http协议四大特性:
1.基于请求响应(必须要由用户先发出请求否则不会响应)
2.基于TCP、IP作用于应用层之上的协议
3.无状态
服务端无法识别客户端的状态
(为了让服务端保存状态 就有了cookie和session)
4.无连接
# 保存在客户端和用户相关的数据都称为cookie
cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上Cookie,这样服务器就能通过Cookie的内容来判断这个是“谁”了。
# 保存在服务端和用户相关的数据称之为session
django操作cookie
# 如果想要客户端保存cookie需要用HttpResonse对象调用方法
def set_cookie(request):
obj = HttpResponse('假日快乐')
# 让浏览器保存用户姓名
obj.set_cookie('name', 'summer')
return obj
1.登录设置cookie
2.多个视图函数都需要校验用户是否登录
装饰器
3.如何记住用户登录之前想要访问的页面 用户登录成功之后自动跳转
场景1:用户访问了其他需要登录才可以访问的页面 如何跳转>>>:想要访问的
场景2:用户直接访问的登录页面 如何跳转>>>:网址首页
print(request.path) # 获取路由后缀
print(request.path_info) #获取路由后缀
print(request.get_full_path()) # 获取url完整路径
# 代码实操:
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 == 'summer' and password == '123':
target_path = request.GET.get('next')
if target_path:
obj = redirect(target_path)
else:
obj = redirect('/home/')
obj.set_cookie('name', 'summer',max_age=10) # 设置超过10秒 cookie就失效
return obj
return render(request, 'login.html')
@login_auth
def home(request):
# if request.COOKIES.get('name'):
return HttpResponse('我是登录之后才可以访问的home页面')
# return redirect('/login/')
@login_auth
def index(request):
# if request.COOKIES.get('name'):
return HttpResponse('我是登录之后才可以访问的index页面')
# return redirect('/login/')
django操作session
# session工作机制 :客户端发送请求,服务端接收到请求以后给客户端发送一串随机字符串,服务端存储随机字符串对应的用户信息,随后客户端发送消息给服务端的时候会携带字符串,服务端接收消息的时候会自动校验用户身份
def set_session(request):
request.session['name'] = 'summer'
# django随机产生一个字符串返回给客户端 给name加密
# 在django_session表中创建数据 对summer加密
return HttpResponse('session里面的set')
'''由于session的工作原理是在服务端保存用户数据 而服务端保存数据一般是使用数据库 所以需要先做数据库迁移命令 否则的话会报错!'''
1.django的session默认保存时间是14天 (上图的expire_date)
2.客户端接收到的键值对 键默认是session id 值是加密的随机字符串
def get_session(request):
print(request.session.get('name'))
# 服务端自动在请求中校验用户的随机字符串
# 拿着字符串去django_session匹配字符串对应的数据
# 如果匹配上了会自动解密并打印出来 如果没有则返回None
print(request.session.values()) # dict_values(['summer'])
print(request.session.keys()) # dict_keys(['name'])
print(request.session.items()) # dict_items([('name', 'summer')])
return HttpResponse('获取session的名字')
session流程解析图
session的存储位置
数据库 :
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认)
缓存数据库 :
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
SESSION_CACHE_ALIAS = 'default'
文件:
SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎
SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()
缓存+数据库:
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎
加密:
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎
session用户登录功能
def s_login(func):
def s_inner(request,*args, **kwargs):
if request.session.get('name'):
res = func(request,*args, **kwargs)
return res
else:
target_path = request.path_info
return redirect(f'/session_login/?next={target_path}')
return s_inner
def session_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'summer' and password == '123':
request.session['name'] = username
request.session.set_expiry(3) # 当前session在3秒后失效
target_path = request.GET.get('next')
if target_path:
return redirect(target_path)
else:
return redirect('/session_index/')
return render(request, 'session_html.html')
@s_login
def session_index(request):
request.session.delete()
return redirect('/session_home/')
@s_login
def session_home(request):
# if request.session.get('name'):
return HttpResponse('登录以后才可以看的home')
session其他操作
request.session.delete() #删除当前会话的所有session数据
request.session.flush # 删除当前的会话数据 并删除当前的cookie
# 设置会话Session和Cookie的超时时间
request.session.set_expiry(value)
* 如果value是个整数,session会在?秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。
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',
]
django中间件使用场景:主要用于全局校验 用户身份,黑名单等!(装饰器)
# django支持自定义中间件,自定义中间件的五个方法
1.process_request:
按照配置文件中注册的中间件,从上而下依次执行每一个中间件里的process_request方法,如果没有就直接跳过,该方法遇到了HttpResonse对象则直接返回
主要用于过滤请求
2.process_response:
从下往上依次执行,没有直接跳过,该方法有两个形参response,request
一般情况下返回response 也可以自己写一个HttpResponse对象返回
主要用于返回HttpResponse对象
3.process_view:
路由匹配成功以后 执行视图函数之前会触发该方法
主要用于代码层面的替换和过滤 该方法可以拿到视图函数的参数
4.process_template_response:
当视图函数执行完毕 返回的对象中有render方法时会触发
主要作用于返回了render方法的响应对象
5.process_exception:
当视图函数报错时会触发该方法
主要用于异常捕获
'''中间件的大多数方法返回值是None的时候表示忽略当前操作进入下一项,只有返回HttpResponse对象时,表示结束请求,直接返回给客户端'''
# process_request方法 最常用的方法!!
from django.utils.deprecation import MiddlewareMixin
class MyMdd1(MiddlewareMixin):
def process_request(self, request):
print('MyMdd1')
class MyMdd2(MiddlewareMixin):
def process_request(self, request):
print('MyMdd2')
view:
def get_md(request):
print('from md')
return HttpResponse('md')
# process_response方法
class MyMdd1(MiddlewareMixin):
def process_request(self, request):
print('MyMdd1')
def process_response(self, request, response):
print('MyMdd1')
# return response # response是视图函数要返回给html页面上的数据 return HttpResponse('md')
return HttpResponse('我是替换的')
class MyMdd2(MiddlewareMixin):
def process_request(self, request):
print('MyMdd2')
def process_response(self, request, response):
print('MyMdd2')
return response
view:
def get_md(request):
print('from md')
return HttpResponse('md')
'''如果在请求的过程中 process_request方法直接返回了HttpResponse对象,那么会直接执行完同层级的process_response以后,结束请求'''
# process_view方法:
def process_view(self, request, view_func, view_args, view_kwargs):
print('mdd1里的view')
def process_view(self,request,view_func, view_args, view_kwargs):
print('mdd2里的view')
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了