首页 > 技术文章 > Session

liubailiang 2019-08-30 16:17 原文

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')

推荐阅读