Django之cookie/session
一:Cookie的由来
大家都知道HTTP协议是无状态的。
无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后面的请求响应情况。
一句有意思的话来描述就是人生只如初见,对服务器来说,每次的请求都是全新的。
状态可以理解为客户端和服务器在某次会话中产生的数据,那无状态的就以为这些数据不会被保留。会话中产生的数据又是我们需要保存的,也就是说要“保持状态”。因此Cookie就是在这样一个场景下诞生。
二:什么是Cookie
Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息。
三:Cookie的原理
cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上Cookie,这样服务器就能通过Cookie的内容来判断这个是“谁”了
四:session
(1)其是保存在服务端的键值对,虽然其是保存在服务端的 但是其依赖于cookie
(2)浏览器访问服务端的时候会携带随机字符串 服务端本地获取随机字符串 与后端的记录做对比
随机字符串1:数据1
随机字符串2:数据2
五:cookie操作
(1)登录操作
def login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') if username == 'SR' and password == '123': obj = redirect('/home/') obj.set_cookie('cookie', 'session') # 设置键值对 return obj return render(request,'login.html',locals())
def home(request):
if request.COOKIES.get('cookie'):
return HttpResponse('登录成功 才能访问')
return redirect('/login/')
PS:
(1)此时如果有很多个类似hone的函数 我们需要写很多判断条件
(2)因此使用装饰器 装饰
(2)装饰器登录操作
def login_auth(func): @wraps(func) def inner(request, *args, **kwargs): # 将request从args中抽取出来 if request.COOKIES.get('cookie'): # 如果获取到值 正常执行代码 res = func(request, *args, **kwargs) return res else: return redirect('/login/') # 没有值跳转到登录界面 return inner
@login_auth
def home(request):
return HttpResponse('登录成功 才能访问')
@login_auth
def index(request):
return HttpResponse('index 登录成功 才能访问')
PS:
(1)此时有两个函数被登录器装饰
(2)我们需要记录上次登录失败的页面 当再次登录成功 重定向到上次失败的页面
(3)登录装饰器进阶版
def login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') if username == 'SR' and password == '123': old_url = request.POST.get('next') # 获取登录接口 if old_url: # 判断用户是直接访问的登陆页面 还是从别的页面的调过来 obj = redirect(old_url) else: obj = redirect('/home/') # 如果直接是登录界面 跳转到首页 obj.set_cookie('cookie', 'session') # 设置键值对 return obj return render(request, 'login.html', locals())
参数:
- key, 键
- value='', 值
- max_age=None, 超时时间
- expires=None, 超时时间(IE requires expires, so set it if hasn't been already.)
- path='/', Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问
- domain=None, Cookie生效的域名
- secure=False, https传输
- httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
删除Cookie
def logout(request): rep = redirect("/login/") rep.delete_cookie("user") # 删除用户浏览器上之前设置的usercookie值 return rep
设置超时时间
max_age=None, 超时时间
expires=None, 超时时间(IE requires expires, so set it if hasn't been already.)
六:session
session
PS:
设置session request.session['name'] = 'jason'
1.django 内部自动生成一个随机字符串
2.将随机字符串和你要保存的数据 写入django_session表中(现在内存中生成一个缓存记录 等到经过中间件的时候才会执行)
3.将产生的随机字符串发送给浏览器写入cookie
获取session request.session.get('name')
PS
1.django内部会自动从请求信息中获取到随机字符串
2.拿着随机字符串去django_session表中比对
3.一旦对应上了就将对应的数据解析出来放到request.session中
django session默认的超时时间是14天
django_session表中的一条记录针对一个浏览器
# 删除当前会话的所有Session数据 request.session.delete() # 删除的是浏览器的sessionid信息
# 删除当前的会话数据并删除会话的Cookie。 request.session.flush() # 将浏览器和服务端全部删除
这用于确保前面的会话数据不可以再次被用户的浏览器访问
例如,django.contrib.auth.logout() 函数中就会调用它。
# 设置会话Session和Cookie的超时时间
request.session.set_expiry(value)
* 如果value是个整数,session会在些秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。