cookie :保存在客户端(浏览器)上的键值对,由服务端设置,浏览器有权禁止cookie写入
session:保存在服务端(服务器)上的键值对,需要依赖cookie
为什么会有这些技术?
- 目的是为了保存客户端的用户状态
- 因为HTTP协议是无状态的
django如何操作cookie
小白必会三板斧
obj=Httpresponse() #利用obj对象才可以操作cookie
return obj
obj=render()
return obj
obj=redirect()
return obj
如何设置cookie
obj.set_cookie('k1','v1') #让浏览器设置键值对
如何获取cookie
request.COOKIES.get('k1') #获取浏览器携带过来的cookie值
如何设置cookie的超时时间
obj.set_cookie('k1','v1',max_age=3)
obj.set_cookie('k1','v1',expires=3)
两个参数都是设置超时时间 并且都是以秒为单位
区别:如果要给IE浏览器设置cookie的超时时间 只能用expires
如何删除cookie(注销退出登录)
obj.delete_cookie('k1')
def login(request):
if request.method=='POST':
username=request.POST.get('username')
password=request.POST.get('password')
if username=='ldd' and password=='123':
#登录成功
obj=redirect('/home/')
obj.set_cookie('whoami','ldd',max_age=5) #告诉浏览器保存一个键值对
return obj
return render(request,'login.html')
def home(request):
#校验用户是否登录
if request.COOKIES.get('whoami'):
return HttpResponse('只有登录的用户才能访问')
return redirect('/login/')
基于cookie实现的登录认证
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
def login(request):
if request.method=='POST':
username=request.POST.get('username')
password=request.POST.get('password')
if username=='ldd' and password=='123':
#登录成功
old_path=request.GET.get('next') #用户下次想要访问的路径
if old_path: #防止用户直接访问的登录页面根本没有想访问的页面
obj=redirect(old_path)
else:
obj=redirect('/home/') #如果真没有 ,直接跳到首页
obj.set_cookie('whoami','ldd') #告诉浏览器保存一个键值对
return obj
return render(request,'login.html')
from functools import wraps
def login_auth(func):
@wraps(func)
def inner(request,*args,**kwargs):
# 校验用户是否登录
if request.COOKIES.get('whoami'):
res=func(request,*args,**kwargs)
return res
else:
target_path=request.path_info #绝对路径 得到url
return redirect('/login/?next=%s'%target_path)
return inner
@login_auth
def home(request):
return HttpResponse('只有登录的用户才能访问')
@login_auth
def index(request):
return HttpResponse('index页面 也需要登录的用户才能访问')
@login_auth
def home(request):
return HttpResponse('reg页面 也需要登录的用户才能访问')
@login_auth
def logout(request):
obj=redirect('/login/')
obj.delete_cookie('whoami')
return obj
django如何操作session
#设置session
request.session['k1']='v1'
第一次设置的时候会报错 是因为没有执行数据库迁移命令 生成django需要用到一些默认表(django_session) django默认的失效时间是14天 2周
'''
request.session['k1']='v1'
'''
这句话到底发生了哪些事
1.django内部自动帮你调用算法生成一个随机的字符串
2.在django_session添加数据(数据也是加密处理)
随机字符串 加密之后的数据 失效时间
sjhhdj gdsag
3.将产生的随机字符串返回给客户端浏览器 让浏览器保存
sessionid :随机字符串
# 会话session的key,拿到随机字符串
request.session.session_key
#获取session
request.session.get('k1')
1.django内部会自动去请求头里获取cookie
2.拿着session所对应的随机字符串去django_session表中一一对比
3.如果对比上了,会将随机字符串对应的数据获取出来 自动放入request.session中
如果没有就是一个空字典
#删除session
request.session.delete()
客户端和服务端全部删除
request.session.flush()
只会根据浏览器的不同删对应的数据
#如何设置失效时间
设置会话session和cookie的超时时间
request.session.set_expiry(value)
*如果value是整数 session会在数秒后失效
*如果value是datatime或timedata,session就会在这些时间后失效
*如果value是0 用户关闭浏览器session就会失效
*如果value是none,session会依赖全局session失效策略
def set_session(request):
request.session['k1']='ldd1'
request.session.set_expiry(5) #键值有效期5秒
request.session['k2']='ldd2'
request.session['k3']='ldd3'
#设置多条数据也只会在服务端存一条数据,只针对不同浏览器存不同数据
return HttpResponse('设置成功')
def get_session(request):
if request.session.get('k1'):
res=request.session.get('k1')
print(res)
return HttpResponse('获取成功')
return HttpResponse('失效了')
def del_session(request):
# request.session.delete() #客户端服务端全部删除
request.session.flush()
return HttpResponse('删除了')
django中间件
class SessionMiddleware(MiddlewareMixin):
def __init__(self, get_response=None):
self.get_response = get_response
engine = import_module(settings.SESSION_ENGINE)
self.SessionStore = engine.SessionStore
def process_request(self, request):
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
request.session = self.SessionStore(session_key)
def process_response(self, request, response):
class CsrfViewMiddleware(MiddlewareMixin):
def process_request(self, request):
csrf_token = self._get_token(request)
if csrf_token is not None:
# Use same token next time.
request.META['CSRF_COOKIE'] = csrf_token
def process_view(self, request, callback, callback_args, callback_kwargs):
if getattr(request, 'csrf_processing_done', False):
return None
def process_response(self, request, response):
class MessageMiddleware(MiddlewareMixin):
"""
Middleware that handles temporary messages.
"""
def process_request(self, request):
request._messages = default_storage(request)
def process_response(self, request, response):
django默认有7个中间件
只要你想要做一些网站的全局性功能 你都应该考虑使用django的中间件
- 全局的用户登录校验
- 全局的用户访问频率校验
- 全局的用户权限校验()
django的中间件是所有框架里面做的最完善的
对象 字符串 》》反射
全局 》中间件
- 并且支持用户自定义中间件 然后暴露给用户五个可以自定义的方法
需要掌握
- process_request
- 请求来的时候会按照settings配置文件中从上往下的顺序 依次执行每一个中间件内部定义的process_request方法 如果中间件内部没有该方法 直接跳过执行下一个中间件
- 该方法一旦返回了HTTPresponse对象,那么请求会立刻停止往后走 原路立即返回
- process_response
- 响应走的时候会按照settings配置文件从下往上的顺序 依次执行每一个中间件内部定义的process_response方法
- 该方法必须有两个形参 并且必须返回response形参 不返回直接报错
- 该方法返回什么(HTTPresponse对象)前端就能获得什么
- 当process_request方法直接返回HTTPresponse对象之后 会直接从当前中间件里面的process_response往回走
- 没有执行的中间件都不会再执行
需要了解
- process_view(self,request,view_name,*args,**kwargs)
- 路由匹配成功之后执行视图函数之前触发
- 如果该方法返回了一个HTTPresponse对象 那么会从下往上依次经过每一个中间件里面的process_response方法
- process_template_response
- 当你返回的对象中含有render属性指向的是一个render方法的时候才会触发 从下往上的顺序
def md(request):
print('我是视图函数md')
def render():
return HttpResponse('我很奇怪')
obj=HttpResponse('我也很体贴')
obj.render=render
return obj
- process_exception
- 当视图函数中出现错误 会自动触发 顺序是从下往上
上面五个方法,会在特定的阶段自动触发
- 如果形参中含有response 那么必须要返回