session 称为“会话控制” 是存放在服务器端的一组数据
在讲session之前首先要说明http的连接是无状态的,即一次请求完成后立即会断开连接,下次重新请求的时候,服务器无法识别当前的用户是谁,所以会引入session和cookie
从本质上看:session和cookie是一样的,都是保存用户的信息,来达到“保持会话”的功能
但cookie是保存在客户端浏览器上的,session是保存在服务器端的
区别:
cookie是暴露在客户端上的,是不安全的,可以被用户随意修改,并且不能无限制的存储数据
session是在服务器端的,不会被用户随意修改,是相对安全的,对数据长度没有限制
session是基于cookie而存在的(如果浏览器关闭保存cookie功能,那么session也不会起作用)
当客户端访问web服务器时,服务器端会首先验证客户端的合法性,验证成功后
服务器端将客户的相关信息存储在session中,同时还会在客户端浏览器cookie中自动的设置随机的session__id
当下次客户端再向服务器发送请求时会携带着cookie一同过来,服务端首先拿到session__id然后去数据库或者缓存或文件中去查询相对应的信息,这样便可知道当下是哪个用户访问了服务器
注意:
当服务器保存Session数据时,会自动的创建一个随机字符串,
并通过 response.set_cookie('session_id') = “随机字符串” 到客户的浏览器上。
session失效的三种方式:
一. 到期之后自动失效:
默认到期时间为2个礼拜,也可以通过 request.session.set_expiry(value=)设置过期时间
客户端浏览器上的session_id会被自动删除,服务器端的sesson过期数据还存在。
二.服务器主动删除服务器端的session数据(没到期之前):
客户端浏览器上的session_id没有到期仍然存在,服务器端的sesssion被删除
session_id = request.session.session_key
request.session.delete(session_id)
三.服务器主动删除客户端浏览器上的session_id所对应的cookie
request.session.clear()
失效的原理:服务器端和浏览器端任意一方的session相关的数据被删除都会使session失效
Session的基本操作:
1 def index(request): 2 # 获取、设置、删除Session中数据 3 request.session['k1'] # 获取键为‘k1’的值 不存在则报错 4 request.session.get('k2') # 获取键为‘k2’的值 不存在返回None 5 request.session['k3'] = 123 # 设置键'k3’的值为 123 6 request.session.setdefault('k4',123) # 存在则不设置 7 del request.session['k1'] # 删除 键'k1' 8 9 # 所有 键、值、键值对 10 request.session.keys() 11 request.session.values() 12 request.session.items() 13 14 # 判断Session中是否存在'k5' 返回True or False 15 request.session.has_key('k5') 16 17 # 用户session的随机字符串 18 request.session.session_key 19 20 # 删除浏览器上的session_id 相当于session过期 21 request.session.clear() 22 23 # 删除所有过期的Session数据 24 request.session.clear_expired() 25 26 # 检查 用户session的随机字符串 在数据库中是否存在 27 request.session.exists("session_key") 28 29 # 删除当前用户的所有Session数据 注意:是删除在服务器端保存的数据 在cookie端保存的session_id不会被删除 一直存在直到下次session到期或者服务器重新设置session时会覆盖原session_id所对应的随机字符串 30 request.session.delete("session_key") 31 32 # 设置session的过期时间 如果不设置,默认是2个礼拜以后过期 当到期之后session将不再生效,原理是浏览器端的session_id将被自动删除 服务器获取不到原来的session_id也就无法去查询服务器端的对应的session_id的数据 33 # 所以需要定期手动删除服务器端已经过期的session数据 34 request.session.set_expiry(value) 35 # 如果value是个整数,session会在些秒数后失效。 36 # 如果value是个datatime或timedelta,session就会在这个时间后失效。 37 # 如果value是0,用户关闭浏览器session就会失效。 38 # 如果value是None,session会依赖全局session失效策略。
通过Session来检查用户是否已经登录(装饰器 可以应用到每个视图函数):
def check_login(func): ''' 检查用户登录状态,已经登录则继续执行需要装饰的视图,退出登录则跳转到登录页面 :param func: :return: ''' def func_in(request, *args, **kwargs): username = request.session.get('username') if username: return func(request,*args, **kwargs) else: return redirect('/login/') return func_in
Session的五种保存方式:
配置settings.py文件可以对session进行一系列的设置
1.数据库
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认)
2.缓存(推荐使用)
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
3.缓存+数据库
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎
4.文件
SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎
SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T
5.加密cookie(客户端浏览器上以cookie加密的方式保存,等同于cookie)
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎
settings.py文件中关于Session的其他设置:
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,默认修改之后才保存
扩展:
因为django前端可以直接获取到request请求的所有信息,因此session不仅可以在后端通过request.session获取到,
还可以在前端通过{{request.session}}获取到,所以session中一般保存用户的信息,不需要通过后端传数据给前端,
而是直接在前端显示用户的信息,减轻服务器后端压力,减少render中传递的数据,简化代码
# 设置session时可以将用户信息封装成一个字典内嵌到session中 不需要再session中设置多个key 方便记忆,管理 request.session['user_info'] = { 'uid' : 1, 'username' : 'jack', 'age' : 18, 'email' : 'jack123455@163.com' } # 服务器后台取值 简单明了 user_info = request.session.get('user_info') uid = user_info.get('uid') username = user_info.get('username') age = user_info.get('age') email = user_info.get('email')