会话控制
阅读 (200890)一、会话控制 COOKIE
1、概述
会话控制 用来保持用户的状态 具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案
2、原因
http协议时无状态的
每一次请求都是一次新的请求,不会记得之前的通信状态
3、值的存储
cookie存储在客户端的浏览器 一般会限制存储cookie的个数为 20个 并且单个cookie保存值的大小不能超过4kb 存储在浏览器上为明文存储 所以不安全
4、设置cookie
-
方法
set_cookie()
-
原型
set_cookie(self, key, value='', max_age=None, expires=None, path='/', domain=None, secure=False, httponly=False)
-
参数
- key cookie的键
- value cookie的值
- max_age 最长使用时间(秒为单位)
- expires 过期时间,优先级高(秒为单位)
- path 生效的路径
- domain 生效的域名
- secure HTTPS传输时应设置为true
- httponly 仅http传输 不能使用js获取cookie
-
示例
设置cookie 不设置过期时间
path('setcookie/',views.set_cookie_view),
def set_cookie_view(req): res = HttpResponse('设置cooke') res.set_cookie('name','lucky') return res
注意:如果没有设置Cookie超时时间,表示关闭浏览器之后自动删除Cookie,Cookie尽量避免存储敏感信息
设置cookie并设置过期时间
url(r'^set_cookie_lifetime/',views.set_cookie_lifetime),
def set_cookie_lifetime(req): res = HttpResponse('设置cooke并设置过期时间') # 设置过期时间为一分钟 # res.set_cookie('name','lucky',max_age=60) res.set_cookie('name','zhangsan',expires=60) return res
5、获取cookie
-
属性
request.COOKIES
-
格式
request.COOKIES.get(key)
-
示例
path('^get_cookie/',views.get_cookie),
#获取cookie def get_cookie(req): print(req.COOKIES) value = req.COOKIES.get('name') return HttpResponse("值为{}".format(value))
6、删除cookie
-
方法
delete_cookie()
-
格式
res.delete_cookie(key)
-
示例
path('^delete_cookie/',views.delete_cookie_view),
def delete_cookie_view(req): res = HttpResponse('删除cookie') res.delete_cookie('name') return res
二、会话控制 SESSION
1、概述
-
说明
服务器需要识别来自同一访问者的请求,这主要是通过浏览的cookie实现的。 访问者在第一次访问服务器时,服务器在其cookie中设置一个唯一的ID号——会话ID。 这样,访问者后续对服务器的访问头中将自动包含该信息,服务器通过这个ID号,即可区 隔不同的访问者
-
会话
客户端与服务端一次通信称之为一次会话
-
http协议时无状态的
每一次请求都是一次新的请求,不会记得之前的通信状态
-
状态保持
将会话信息得到存储
-
存储的位置
存储在服务端:session
-
Session存储结构
以键值对方式存储
2、启用session
-
settings.py文件
INSTALLED_APPS = [ 'django.contrib.sessions', ] MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', ]
-
注意
启用session后request对象才会有session属性
3、使用session
-
生成session存储所需要的系统表
python manage.py migrate
-
设置session不设置过期时间
-
格式
request.session[key] = value
def set_session(req): req.session['name'] = 'lucky' req.session['sex'] = 'man' return HttpResponse('设置session')
注意:session默认存活时间为 俩周
可以去库中查看django_session表 把session的值使用base64解码出来
-
-
设置session并设置过期时间
-
格式
request.session.set_expiry(value)
value值:
- integer 整数 秒
- 0 当前浏览会话结束
- datetime
- timedelta
- None 依赖于全局session过期
def set_session_lifetime(req): req.session.set_expiry(60) #过期时间1分钟 req.session['name'] = 'lucky' return HttpResponse('设置session并设置过期时间')
-
-
获取 session
def get_session(req): v = req.session.get('name','default') return HttpResponse('获取session-----{}'.format(v))
-
删除 session
- clear() 清空所有session 会将session存储数据删除 但是不会将表中的整条session数据清除
- flush() 清空所有 并删除表中的session数据
- logout(request) 清空所有 并删除表中的session数据
- del request.session[key] 删除某个session的值
from django.contrib.auth import logout def del_session(req): req.session.flush() # 清除所有session req.session.clear() # 清除所有session 不删除表中数据 logout(req) # 清除所有session del req.session['name'] # 删除key为name的session return HttpResponse('清除session')
4、存储原理
5、存储位置
-
基于数据库的会话
默认的会话存储方式
SESSION_ENGINE = "django.contrib.sessions.backends.db"
-
基于缓存的会话
只存在本地内存中,如果丢失则不用找回,但是比数据库的方式读写更快
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
-
基于缓存和数据库的会话
优先从本地缓存中获取,如果没有则从数据库中获取再同步到缓存
SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
-
redis作为缓存使用
安装
- sudo pip install redis
- sudo pip install django-redis-sessions==0.5.6
配置
SESSION_ENGINE = "redis_sessions.session" SESSION_REDIS_HOST = "10.0.12.34" # 主机 SESSION_REDIS_POST = 6379 # 端口 SESSION_REDIS_DB = 0 # 选择数据库 SESSION_REDIS_PASSWORD = "lucky" # 密码 SESSION_REDIS_PREFIX = "session" # 前缀
6、cookie 和session 的区别
-
cookie数据存放在客户的浏览器上,session数据放在服务器上。
-
cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗 ,考虑到安全应当使用session
-
session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE
-
单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie
-
所以个人建议
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中
7、状态保持示例代码
-
路由
path('index/', views.index), path('login/', views.login), path('dologin/', views.dologin), path('logout/', views.logout),
-
视图
from django.shortcuts import render,HttpResponse,redirect,reverse # 首页 def index(req): return render(req, 'index.html') # 登录 def login(req): return render(req,'login.html') # 登录处理 def dologin(req): username = req.POST.get('username') userpass = req.POST.get('userpass') if username=='lucky' and userpass=='lucky123456': req.session['uid'] = 1 req.session['username'] = username return redirect(reverse('App:index')) return redirect(reverse('App:login')) # 退出登录 def logout(req): req.session.flush() return HttpResponse("<meta http-equiv='refresh' content='4;/'>退出成功4秒后条到首页 如不能跳到首页 请手动点击<a href='/'>首页</a>")
-
模板
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> <style> nav{ width: 100%; height: 40px; background-color: #000; line-height: 40px; } nav span{ float: right; color: #fff; margin-right: 20px; } nav>span>a{ color:#fff; font-size: 16px; text-decoration: none; } </style> </head> <body> <nav> {% if username %} <nav><span>欢迎:{{ username }} | <a href="{% url 'App:logout' %}">退出登录</a></span></nav> {% else %} <span><a href="{% url 'App:login' %}">登录</a> | <a href="#">注册</a></span></nav> {% endif %} <h1>首页</h1>
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <marquee behavior="" direction=""><h2>登录</h2></marquee> <center> <form action="{% url 'App:dologin' %}" method="POST"> <p>用户名: <input type="text" name="username" minlength="6" maxlength="10" placeholder="请输入用户名..."></p> <p>密码: <input type="text" name="userpass" onkeyup="(this.v=function(){this.value=this.value.replace(/[^0-9-]+/,'');}).call(this)" onblur="this.v();" placeholder="请输入密码..." maxlength="10"></p> <p><input type="submit" value="submit"></p> </form> </center> </body> </html>