一、http协议无状态问题

http协议没有提供多次请求之间的关联功能,协议的本意也并未考虑到多次请求之间的状态维持,每一次请求都被协议认为是一次性的。但在某些场景下,如一次登录多次访问,我们希望可以保存登录状态,协议并没有直接提供会话跟踪的支持,需要靠其他手段来帮助实现目标。

二、会话跟踪技术--cookie

1、对cookie的理解

  • cookie是一个key-value的数据结构(类似python字典),用于保存需要维护状态的数据cookiesession最大的区别是cookie的数据保存在客户端,而session把数据保存在服务端。

  • cookie一般由服务器设置,并可以存放在http的请求头和响应头中。

  • cookie由浏览器保存,浏览器已经实现了cookie的保存和发送,而服务器上对cookie的设置和接收则需要我们配置。

  • 通过cookie,可以在多个会话之间共享一些必要的信息如登录状态数据、历史访问记录、个性化定制设置等,以实现会话跟踪,让用户感觉到网站可以'记录'自己的偏好,减少不必要的重复输入,从而提升用户体验。

2、cookie的使用接口

django的服务端发送响应有三种方式:

1. return HttpResponse()
2. return render()
3. return redirect()

这三种方法实例化的结果都是HttpResponse类的实例,可以直接用于设置cookie

response对象上执行set_cookie(key,value,...)即可设置cookie, 其中特别注意cookie属性的设置。

cookie的设置

服务器在响应对象上进行set_cookie操作,一旦设置完成,客户端后续的请求就可以根据cookie的属性规则携带cookie数据。

def set_cookie(key, value='', max_age=None, expires=None, path='/',
domain=None, secure=False, httponly=False, samesite=None)

cookie的获取

服务器在请求对象上通过request.COOKIES得到cookie字典数据,注意此处拿到的cookie数据从安全性来说是未被验证正确性的。

@cached_property
def COOKIES(self):
raw_cookie = get_str_from_wsgi(self.environ, 'HTTP_COOKIE', '')
return parse_cookie(raw_cookie)

注意1:cookie在set的时候可以设置它被发送的范围,每个cookie都有对应的domain+path的属性,这约束了cookie发送范围,只有当http的请求落在此范围中的url,才会携带此cookie。

注意2:一个cookie就是一个key-value项,不过它还携带有属性。一个cookies是一个字典,保存了很多cookie项,注意单个cookie项和整个cookies字典的关系。

3、cookie的属性

max_age:
失效延迟时间,单位是秒,设置成15秒意味着在设置完之后的15秒之内,此cookie有效,超时之后cookie失效,浏览器会删除失效的cookie。此参数默认是None,代表着直到浏览器关闭,即默认是会话cookie。
注意:如果max_age是0,意味着让浏览器立刻删除此cookie,即此cookie即刻失效。 expires:
指定失效日期,同样用于失效cookie,只不过是另一种时间指定方式。 domain:
此cookie可以被使用的域名范围。 path:
与domain配合着使用,默认是根路径'/',意味着在当前domain范围下任何url都会携带此cookie。可以主动设置其他的路径以缩小发送的范围,从而约束某一个cookie项只应用于某些url。 secure:
默认是False,一般配合https协议使用,在https协议下,只有secure属性是True的cookie才允许被发送。 httponly:
默认是False,这意味着js也可以通过document.cookie来访问和设置此cookie,而如果设置为True,则代表只允许服务端来访问和设置此cookie。

4、使用cookie的问题

cookie的安全性问题

服务器是根据客户端发送过来的cookie进行状态判断,这种保存在客户端的cookie数据非常容易修改和伪装,服务器基本无法知晓cookie的正确性,也就不能100%信任cookie的数据。

此外,cookie很容易被盗取,如果客户端cookie里面包含私密数据的话,就更不安全了。

cookie的覆盖问题

在服务端上设置的新的cookie会让客户端更新本地cookie

cookie的合理性问题

什么样的数据适合放到cookie中?

cookie中的数据是每次交互都要被传输的,所以我认为:

  • 应该是常用的数据,如果不常用只会浪费带宽减少效率,最好是多次交互中都要使用或者修改
  • 应该是小数据量
  • 不应该是非常私密的数据,否则:要么在客户端上容易被盗取,要么在传输中容易被截取

所以cookie特别适合发送sessionid,它能满足上述所有条件。

cookie的存储问题

cookie是客户端临时存储,按规定单个cookie文件存储量最大是4kb,每个域下的cookie文件不能超过20个,不应该将cookie作为存储功能的滥用,要使用客户端存储功能应该启用localstorage

cookie的访问限制问题

jsdocument.cookie可以获取cookie数据,将会在控制台输出一个字符串格式的key-value数据,如果此cookie的属性是httponly=true就不能通过此方法获取。

三、会话跟踪技术--session

1、对session的理解

session把数据存放在服务器上,并使用一个标签session-key唯一标记此数据。session-key作为cookie发送给客户端,即客户端只保存session-key,然后通过cookie发送给服务端,以表明身份,所以sessioncookie安全。

每一次请求到达服务器的时候,服务器获取cookie中保存的session-key,并在数据库django-session表中寻找对应的session-data,进一步处理业务逻辑。

session的使用有如下优点:

1、数据保存在服务端,客户端仅保存一个senssionid

2、sessionid数据量很小,适合每次发送

3、安全性,sessionid是一个随机字符串,不携带任何私密数据

2、session的使用接口

session的设置

django实现了session,帮我们完成了很多操作,且提供使用的接口非常简单:

request.session['name'] = 'xxx'

设置session的时候会执行如下三个操作:

1、创建一个随机字符串作为sessionid
2、把sessionid作为session-key,以及一个session_data字典加入到django-session表中
3、set-cookie,把sessionid发送给客户端

注意1:从底层源码来看,session_data其实就是一个字典{},然后通过orm存到django_session表中(应该有dict-->str的序列化和加密操作)

注意2:如果发现客户端的cookie中含有seesionid说明不是第一次登录,将会使用此sessionid并更新此sessionid对应的session_data数据

注意3:如果有两个用户在同一台电脑的同一个浏览器上,访问同一个url,因为sessionid是作为cookie存在,所以两个人会使用同一个sessionid。

而对于服务器而言,只认sessionid不认人,使用同一个sessionid的操作会覆盖之前的数据以导致在服务端上的session_data数据会相互覆盖,这样的结果是数据紊乱(尤其当两人的数据项目数量不一致时更严重)

session的读取

读取session的接口同样很简单:

name = request.session['name']

读取的时候会执行如下三个操作:

1、获取request.COOKIES中的sessionid
2、拿着sessionid作为session_key到数据库的django-session表中查找对应的session-data,底层就是执行orm的objects.filter(session_key=sessionid)
3、获取session-data中的数据并进一步处理

session的删除

删除session的接口:

1、del request.session[xxx]   # 删除一个会话数据属性
2、request.session.flush() # 删除所有会话数据

清空会话信息时会执行如下操作:

1、删除django-session表中的session-key=sessionid的记录,底层操作就是执行orm的objects.filter(session_key=sessionid).delete()
2、删除response中的cookie里的sessionid记录

注意1:服务器把sessionid作为cookie的数据发给客户端保存,一般是会话cookie即不关闭浏览器程序就可以一直保持会话跟踪。但一旦客户端关闭了浏览器,则此sessionid便不再有效。但django颁发的cookie默认有效时间是2周,所以cookie会被保存到客户端硬盘上,即使关闭了浏览器也继续保存。

注意2:因为服务器无法获知客户端浏览器将会在什么时候关闭,更无法获知浏览器什么时候会执行清空cookie的操作。客户端一般只有在logout的时候才会主动告知删除session,其他情况下浏览器不会主动告知,所以服务器的session不能无限保存,被迫要设置失效时间(不然存储空间浪费),在一定时间内如果还没有用户重新访问此session,便被服务端认为此用户已失效,进而可以删除session数据。

3、session的属性

settings中还可以配置全局的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,默认修改之后才保存(默认)

4、使用session的问题

1、session的正常工作依赖于cookie的启用,如果客户端禁用cookie功能,该如何保证session正常工作?---重写URL

2、同一台电脑同一个浏览器,访问同一个url,保存着同一个sessionid,如何处理多用户使用同一sessionid登录而导致的数据紊乱问题?---使用用户认证组件,使用账户密码来区别用户

四、总结

1、cookie和session都是为了解决http协议自身并不支持状态维持的缺点。

2、会话跟踪的目的是为了让多次请求之间可以共享数据,以提供更好的用户体验。

3、cookie和session都需要保存状态维持数据,只不过cookie是保存在客户端,session是保存在服务端。

4、分析和研究两者的技术相同点和区别有助于加深对会话跟踪的理解和使用。

django框架--cookie/session的更多相关文章

  1. 第三百一十三节,Django框架,Session

    第三百一十三节,Django框架,Session Django中默认支持Session,其内部提供了5种类型的Session供开发者使用: 1.数据库(默认)2.缓存3.文件4.缓存+数据库5.加密c ...

  2. day09 Django: 组件cookie session

    day09 Django: 组件cookie session   一.cookie和session都是会话跟踪技术     1.什么是会话             可以理解为客户端和服务端之间的一次会 ...

  3. Django框架-cookie和session以及中间件

    目录 一.cookie 和 session 1.为什么会有这些技术 2. cookie 2.1 Django如何设置cookie 2.2 Django如何获取cookie 2.3 Django如何设置 ...

  4. python框架之Django(7)-Cookie&Session使用

    Cookie 添加 response.set_cookie 添加明文cookie response.set_cookie(key, value='', max_age=None, expires=No ...

  5. Django实现cookie&session以及认证系统

    COOKIE&SESSION 知识储备 由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生. cookie的工作原理是:由服务器产生内 ...

  6. Django之Cookie Session详解,CBV,FBV登陆验证装饰器和自定义分页

    Cookie Session和自定义分页   cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接 ...

  7. Django 之 cookie & session

    Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后面 ...

  8. Django的Cookie Session和自定义分页

    cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不 ...

  9. django - 总结 - cookie|session

    Cookie是通过HTTP请求和响应头在客户端和服务器端传递的. 在Web开发中,使用session来完成会话跟踪,session底层依赖Cookie技术. --------------------- ...

随机推荐

  1. 微信小程序 发送模版消息

    微信小程序开发之发送模板消息 1,小程序wxml页面form表单添加 report-submit="true" <form bindsubmit="sub" ...

  2. angular2+ 初理解

    一.Angular Module     1.angular 模块是一个类,它需要NgModule这个装饰器函数接受一个原数据对象作为参数来描述这个模块类属性.     其中最重要的属性有:      ...

  3. HDU1241 Oil Deposits 2016-07-24 13:38 66人阅读 评论(0) 收藏

    Oil Deposits Problem Description The GeoSurvComp geologic survey company is responsible for detectin ...

  4. Lucene原理一

    Lucene 是一个高效的,基于Java 的全文检索库. 所以在了解Lucene之前要费一番工夫了解一下全文检索. 那么什么叫做全文检索呢?这要从我们生活中的数据说起. 我们生活中的数据总体分为两种: ...

  5. Mysql工作記錄之修改默認存儲引擎及重設root用戶密碼

    1>修改默認存儲引擎方法 修改配置文件,然後重啟mysql服務: [root@CHW mysql]# cat /etc/my.cnf                            [my ...

  6. 谷类 cereal

  7. Windows Phone 8.1 生命周期调试

    之前重装了机子,今天调试时突然找不到调试生命周期的菜单栏了.最后找了5分钟,终于找回来了,特此记录以免以后重装后再出现这种状况. 项目启动调试后: 这样是没有显示调试生命周期的,接下来在工具栏右键: ...

  8. SQLite3动态库、静态库编译

    资源准备 1.下载SQLite3源码,下载地址为https://www.sqlite.org/download.html.下载sqlite-amalgamation-3200000.zip和sqlit ...

  9. 测试一下你的T-SQL基础知识-subquery

    一直以为自己SQL挺好的,没有想到今天在重构存储过程遇到了一个子查询的问题,修改为自连接之后发现居然结果不对,于是有了下面的测试.假设表中有如下数数据,请问Query1,Query2,Query3的查 ...

  10. C# 读取Excel表格内容,以及NPOI的使用

    在实际的开发中,我们可能需要读写word或者Excel的内容,在我开发的项目中,需要读取Excel的内容,并将相对应的内容存储到数据库中,这里简单跟大家分享一下,希望能够帮助一些人. 我相信在读写wo ...