Cookie和Session
一、cookie和session的介绍
cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生。cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁”了。
cookie虽然在一定程度上解决了“保持状态”的需求,但是由于cookie本身最大支持4096字节,以及cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是session。
cookie和session的区别
Cookie是保存在用户浏览器端的键值对,Session是保存在服务器端的键值对;Cookie做用户验证的时,敏感信息不适合放在Cookie中,别人可以分析存放在本地的Cookie并进行Cookie欺骗,考虑到安全应当使用Session;用户验证时两者要结合使用,Session可保存到文件,内存,数据库任意地方.cookie存储到客户端
优点:数据存储在客户端。减轻服务端的压力,提高网站的性能
缺点:安全性不高,在客户端很容易被查看或破解用户会话信息
session存储到服务器
优点:安全性高
缺点:服务器压力大
Cookie的简单使用
1、获取Cookie
request.COOKIES.get("islogin",None) #如果有就获取,没有就默认为none
request.COOKIES['key']
request.COOKIES.get('key')
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
参数:
default: 默认值
salt: 加密盐
max_age: 后台控制过期时间
2、设置cookie
rep = HttpResponse(...) 或 rep = render(request, ...) #return的对象
rep.set_cookie(key,value,...)
rep.set_cookie("haiyan","344",20) #20代表过期时间
# 普通cookie是明文传输的,可以直接在客户端直接打开,所以需要加盐,解盐之后才能查看
rep.set_signed_cookie(key,value,salt='加密盐',...)
参数:
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传输改为True
httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖
复制代码
# max_age 10秒失效
result.set_cookie('username',u,max_age=10)
# expires 设置失效日期
import datetime
current_date = datetime.datetime.utcnow()
current_date = current_date + datetime.timedelta(seconds=5)
result.set_cookie('username',u,expires=current_date)
# 加密
obj = HttpResponse('s')
obj.set_signed_cookie('username',"kangbazi",salt="asdfasdf")
request.get_signed_cookie('username',salt="asdfasdf")
3、删除Cookie
obj.delete_cookie("cookie_key",path="/",domain=name)
session的简单使用
1、获取session
# 获取Session中数据
request.session['k1']
request.session.get('k1', None)
2、设置session
# 生成Session中数据
request.session['k1'] = 123
request.session.setdefault('k1', 123) # 不存在则设置
3、删除session
# 删除Session中某条数据
del request.session['k1']
# 删除当前用户的所有Session数据
request.session.delete("session_key")
request.session.clear()
request.session.flush() # 删除当前的会话数据和会话cookie。经常用在用户退出后,删除会话。
# 登出时使用flush()方法是比较安全的一种做法,而且一次性将session中的所有内容全部清空,确保不留后患。但也有不好的地方,那就是如果你在session中夹带了一点‘私货’,会被一并删除,这一点一定要注意。
4、类似字典数据类型的内置方法
request.session.keys()
request.session.values()
request.session.items()
request.session.setdefault('k1', 123)
request.session.clear()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems()
5、其他方法
# 用户session的随机字符串
request.session.session_key
# 将所有Session失效日期小于当前日期的数据删除
request.session.clear_expired()
# 检查用户session的随机字符串是否 在数据库中
request.session.exists("session_key")
request.session.set_expiry(value)
# 设置cookie的有效期。可以传递不同类型的参数值:
• 如果值是一个整数,session将在对应的秒数后失效。例如request.session.set_expiry(300) 将在300秒后失效.
• 如果值是一个datetime或者timedelta对象, 会话将在指定的日期失效
• 如果为0,在用户关闭浏览器后失效
• 如果为None,则将使用全局会话失效策略
失效时间从上一次会话被修改的时刻开始计时。
request.session.get_expiry_age()
# 返回多少秒后失效的秒数。对于没有自定义失效时间的会话,这等同于SESSION_COOKIE_AGE.
# 这个方法接受2个可选的关键字参数
• modification:会话的最后修改时间(datetime对象)。默认是当前时间。
•expiry: 会话失效信息,可以是datetime对象,也可以是int或None
set_test_cookie()
# 设置一个测试cookie,用于探测用户浏览器是否支持cookies。由于cookie的工作机制,你只有在下次用户请求的时候才可以测试。
test_cookie_worked()
# 返回True或者False,取决于用户的浏览器是否接受测试cookie。你必须在之前先调用set_test_cookie()方法。
delete_test_cookie()
# 删除测试cookie。
session的存储
Django提供了一个通用的Session框架,并且可以使用多种session数据的保存方式:
- 保存在数据库内
- 保存到缓存
- 保存到文件内
- 保存到cookie内
通常情况,没有特别需求的话,请使用保存在数据库内的方式,尽量不要保存到Cookie内。
1.数据库存储session
Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session表中
配置settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认)
SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认)
SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认)
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认)
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认)
# 设置Ture后,每次点击页面,时间更新
2.缓存存储session
配置settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径
SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名
SESSION_COOKIE_SECURE = False # 是否Https传输cookie
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期
SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存
可以设置为Memcache缓存
配置settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
SESSION_CACHE_ALIAS = 'db' # 使用的缓存别名,此处别名依赖缓存的设置
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
},
'db': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}
3.使用redis缓存session
SESSION_ENGINE='redis_sessions.session'
SESSION_REDIS_HOST='localhost'
SESSION_REDIS_PORT=6379
SESSION_REDIS_DB=0
SESSION_REDIS_PASSWORD=''
SESSION_REDIS_PREFIX='session'
#通过redis-cli客户端可以查看:
127.0.0.1:6379> select 0
OK
127.0.0.1:6379[0]> keys *
1) "session:0bjyuegx0i5ivyuzpb8ezgo0b35u2z4v"
4.文件存储session
配置 settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎
SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()
# 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T
SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径
SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名
SESSION_COOKIE_SECURE = False # 是否Https传输cookie
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期
SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存
5.缓存加数据库session
数据库用于做持久化,缓存用于提高效率,先去缓存中取数据,缓存没有再去数据库中取,然后在缓存中存一份
配置settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎
6.加密cookie session
数据都存在于客户端
配置settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎
示例:
from django.shortcuts import render,redirect
# Create your views here.
import datetime
def login(request):
print("COOKIES",request.COOKIES) #打印cookies 一个字典,里面多个键值对
print("SESSION",request.session) #session为服务器对应客户信息的键
if request.method=="POST":
name=request.POST.get("user")
pwd=request.POST.get("pwd")
if name=="yuan" and pwd=="123":
# ret=redirect("/index/")
# 给对象ret设置cookie 安全性较差 ,设定有效时间max_age,expires,
# ret.set_cookie("username",{"11":"22"},max_age=10,expires=datetime.datetime.utcnow()+datetime.timedelta(days=3))
# return ret
# COOKIE SESSION一起使用
# session 以字典存放在服务器端,发给客户端的是数据对应的键,
request.session["is_login"]=True # 在session中增加键值对
request.session["user"]=name
return redirect("/index/")
return render(request,"login.html")
def index(request):
if request.COOKIES.get("username",None): # 取不到设置默认值为None
name = request.COOKIES.get("username",None)
return render(request, "index.html", locals())
# session验证 存在数据库中,所以要先makemigrations生成数据库
if request.session.get("is_login",None):
name=request.session.get("user",None)
return render(request,"index.html",locals())
else:
return redirect("/login/")
##session获取
request.session.get("user",None)
# 设置
request.session["user"]=name
# 删除
del request.session.get("user")
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。