Session:在计算机中,尤其是在网络应用中,称为“会话控制”

Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。

当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象;当会话过期或被放弃后,服务器将终止该会话。

Session 对象最常见的一个用法就是存储用户的首选项。

Session的特点

  1. 依赖cookies
  2. 存储敏感、重要的信息
  3. 支持更多字节
  4. Session共享问题

Session配置和存储

启用Session

Django项目默认启用Session

可以在settings.py文件中查看,如图所示

session中间件

如需禁用session,将上图中的session中间件注释掉即可。

存储方式

settings.py文件中,可以设置session数据的存储方式,可以保存在数据库、本地缓存等。

数据库

存储在数据库中,如下设置可以写,也可以不写,这是默认存储方式

1
SESSION_ENGINE='django.contrib.sessions.backends.db'

如果存储在数据库中,需要在项INSTALLED_APPS中安装Session应用。

session_app

数据库中的表如图所示

session数据库

表结构如下

session表结构

由表结构可知,操作Session包括三个数据:过期时间

本地缓存

存储在本机内存中,如果丢失则不能找回,比数据库的方式读写更快。

1
SESSION_ENGINE='django.contrib.sessions.backends.cache'

混合存储

优先从本机内存中存取,如果没有则从数据库中存取。

1
SESSION_ENGINE='django.contrib.sessions.backends.cached_db'

Redis

在redis中保存session,需要引入第三方扩展,我们可以使用**django-redis**来解决。

1) 安装扩展

1
pip install django-redis

2)配置

在settings.py文件中做如下设置

1
2
3
4
5
6
7
8
9
10
11
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"

Session操作

通过HttpRequest对象的session属性进行会话的读写操作。

1) 以键值对的格式写session。

1
request.session['键']=值

2)根据键读取值。

1
request.session.get('键',默认值)

3)清除所有session,在存储中删除值部分。

1
request.session.clear()

4)清除session数据,在存储中删除session的整条数据。

1
request.session.flush()

5)删除session中的指定键及值,在存储中只删除某个键及对应的值。

1
del request.session['键']

6)设置session的有效期

1
request.session.set_expiry(value)
  • 如果value是一个整数,session将在value秒没有活动后过期。
  • 如果value为0,那么用户sessionCookie将在用户的浏览器关闭时过期。
  • 如果valueNone,那么session有效期将采用系统默认值,默认为两周,可以通过在settings.py中设置**SESSION_COOKIE_AGE**来设置全局默认值。

session模拟用户登录

登录及设置登录标识

  • 视图实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from django.views import View
from django.http.response import JsonResponse


class Login(View):
@staticmethod
def post(request):
query_dict = request.POST # 获取表单参数
userName = query_dict.get('userName', None)
password = query_dict.get('password', None)
if userName == "mac" and password == '123321': # 校验用户是否登录成功
request.session['userName'] = userName # 登录成功,设置session
return JsonResponse({"code": 200, "msg": "OK"})
else:
return JsonResponse({'code': 200, 'msg': "FAIL"})

登录校验

  • 视图实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from django.http import JsonResponse
from django.views import View


class UserInfo(View):
@staticmethod
def get(request):
userName = request.session.get('userName', None) # 获取session,判断用户是否已经登录
if userName is not None:
return JsonResponse({
"code": 200,
"msg": "OK",
"userInfo": {
"userName": userName,
"gender": "男",
"email": "mac321@163.com"
}
})
else:
return JsonResponse({
"code": 200,
"msg": "FAIL"
})

Cookie VS Session

Web应用程序是使用HTTP协议传输数据的。**HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话**。要跟踪该会话,必须引入一种机制。

实现状态保持的方案:

  • 修改Http协议,使得它支持状态保持(难做到)

  • Cookies:通过客户端来保持状态信息

    • Cookie是服务器发给客户端的特殊信息
    • Cookie是以文本的方式保存在客户端,每次请求时都带上它
  • Session:通过服务器端来保持状态信息

    • Session是服务器和客户端之间的一系列的交互动作

    • 服务器为每个客户端开辟内存空间,从而保持状态信息

    • 由于需要客户端也要持有一个标识(id),因此,也要求服务器端和客户端传输该标识,

    • 标识(id)可以借助Cookie机制或者其他的途径来保存

COOKIE机制

Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IENetscapeFirefoxOpera等都支持Cookie

  由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理

  Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用**response向客户端浏览器颁发一个Cookie**。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。

Cookie具有不可跨域名性。根据Cookie规范,浏览器访问Google只会携带GoogleCookie,而不会携带BaiduCookieGoogle也只能操作GoogleCookie,而不能操作Baidu的Cookie

Cookie的基本特点

Cookie保存在客户端

只能保存字符串对象,不能保存对象类型

需要客户端浏览器的支持,浏览器用户可能会禁用Cookie

采用Cookie需要解决的问题

Cookie的创建

  • 通常是在服务器端创建的

  • 服务器通过在http的响应头加上特殊的指示,那么浏览器在读取这个指示后就会生成相应的cookie

Cookie存放的内容

  • 业务信息("key","value")

  • 过期时间

  • 域和路径

浏览器是如何通过Cookie和服务器通信?

  • 通过请求与响应,cookie在服务器和客户端之间传递

  • 每次请求和响应都把cookie信息加载到响应头中;依靠cookiekey传递。

SESSION机制

除了使用CookieWeb应用程序中还经常使用Session来记录客户端状态。 Session是服务器端使用的一种记录客户端状态的机制 ,使用上比Cookie简单一些,相应的也增加了服务器的存储压力

如果说 Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。

每次客户端发送请求,服务断都检查是否含有sessionId

如果有,则根据sessionId检索出session并处理;如果没有,则创建一个session,并绑定一个不重复的sessionId

基本特点

状态信息保存在服务器端。这意味着安全性更高

通过类似与Hashtable的数据结构来保存,能支持任何类型的对象(session中可含有多个对象)

保存会话id的技术,依赖于 Cookie。这是默认的方式,在客户端与服务器端传递 SeesionId

缺点:客户端可能禁用Cookie

  • 表单隐藏字段,在被传递回客户端之前,在 form 里面加入一个hidden域,设置SeesionId

    1
    <input type=hidden name=jsessionid value="3948E432F90932A549D34532EE2394"/>
  • URL重写,直接在URL后附加上SeesionId的信息

总结

两种状态跟踪机制的比较

Cookie Session
存储位置 保持在客户端 保存在服务器端
存储类型 只能保持字符串对象 支持各种类型对象
实现机制 通过过期时间值区分Cookie的类型 需要SeesionId来维护与客户端的通信
会话Cookie——负数表示关闭浏览器销毁Cookie Cookie(默认)
普通Cookie——正数是设置的销毁时间,单位是秒 表单隐藏字段
不支持Cookie——0表示立即销毁Cookie *url*重写