共计 5283 个字符,预计需要花费 14 分钟才能阅读完成。
一、会话控制 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='https://www.zutuanxue.com/'> 首页 </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>