session

安全客
• 阅读 1321

1. 概念:

  • 是一个数据对象,用来存储信息。
  • 是一个抽象对象,指代多个有关联的http请求所构成的一个会话。多次请求之间能够共享一些信息。

2. 实现方案:

  • 方案1:在每个请求的参数或者数据中带上相关的信息。不受 cookie 限制,但是受到 请求长度的限制。
  • 方案2:用 cookie 存储,可以是整个session 的具体数据,也可以是 session的标识(sessin_id).

3. 特点:

  • 只存在于 服务端。
  • 并不是 服务器 原生支持的。是中间件自己创建并管理的。
  • session 仅仅是一个对象信息,可以存到 cookie ,也可以存到任何地方(如内存,数据库)。
  • 存到哪,可以开发者自己决定。
  • session_id,是唯一的标识 session 的,以及其他一些必要信息会放在 cookie 中,一起返回到前端。
  • 其他信息,可以保存在 session_id 命名的文件中。

4. session 的负面影响:

  • 性能影响。如果用户很多,信息都保存在 sessin 文件中,查找耗时太多(可以分目录和哈希等)。
  • 可以自己实现session,将session信息存放到 数据库当中,这样做最好对数据库进行一下缓存的设置了,不然对上千万的数据进行太频繁的检索,也是蛮耗资源的。

5. session 的清除:

  • 定期清理 session(清除服务端的 session 文件,和 客户端的 cookie 信息)
  • cookie, expires 设置为 过去的时间/max-age = 0,客户端的cookie 信息就会过期,浏览器就会自动删除。

6. koa-session 的 原理:

  • 【有空一定要看看源码,看源码要注意命名、特色、知识点的学习。也会学习 koa 插件的写法的过程】【看源码,要先有整体把控图,然后逐步去分析啊】
  • 使用流程:

    • app.use(session(CONFIG, app)); // 初始化koa-session中间件
    • let n = ctx.session.views || 0; // 每次都可以取到当前用户的session
  • 初始化的时候,把 session 对象挂载在 app.context上。所以后面可以 从 ctx.session 上获得 session
  • 在接到 http 请求的时候,
  • 默认把数据 json ,塞进了 cookie ,即 cookie 来存储加密后的 session 信息。
  • 如果设置了外部 store ,会调用 store.set() 去保存 session 。具体的保存逻辑,保存到哪里,由 store 对象自己决定!
  • 用 cookie 存储的时候,对session(包含过期时间)序列化后做一个简单的base64编码。
  • 就算信息保存在文件中,还是必不可少的需要 cookie
  • session_id 的默认实现是 一个时间戳加随机字符串。
  • koa-session允许用户在config中配置自己的编码和解码函数,因此完全可以使用自定义的加密解密函数对session进行编解码

7. session 的鉴权过程:

  • 用户登录的时候,服务端生成一个会话和一个id标识
  • 会话id在客户端和服务端之间通过cookie进行传输
  • 服务端通过会话id可以获取到会话相关的信息,然后对客户端的请求进行响应;如果找不到有效的会话,那么认为用户是未登陆状态
  • 会话会有过期时间,也可以通过一些操作(比如登出)来主动删除

8. 分布式 session:

  • 问题:分布式环境下,前后访问的服务器不同,所以导致 session 不能准确保存

    • 解决方案:将 session 信息放在一个独立的机器上(可以是一个独立的数据库服务,也可以是一个缓存服务)
    • 缺点:但是这个持久层一旦挂了,就会单点失败。
    • 新方案:索性不保存session 数据,所有数据保存在客户端,每次请求都发回服务器(这就是 token)

9. cookie 和 session 的区别:

  • 存储位置不同:cookie -> 客户端浏览器。session -> 服务器
  • 隐私策略不同:cookie -> 不是很安全,cookie 劫持。session -> 相对安全
  • 性能不同:session -> 访问量太大时,占用服务器性能
  • 存储大小不同:cookie -> 有大小限制,一般不超过4K

10. 使用session需要考虑的问题

  • 将 session 存储在服务器里面,当用户同时在线量比较多时,这些 session 会占据较多的内存,需要在服务端定期的去清理过期的 session
  • 当网站采用集群部署的时候,会遇到多台 web 服务器之间如何做 session 共享的问题。因为 session 是由单个服务器创建的,但是处理用户请求的服务器不一定是那个创建 session 的服务器,那么该服务器就无法拿到之前已经放入到 session 中的登录凭证之类的信息了。
  • 当多个应用要共享 session 时,除了以上问题,还会遇到跨域问题,因为不同的应用可能部署的主机不一样,需要在各个应用做好 cookie 跨域的处理。
  • sessionId 是存储在 cookie 中的,假如浏览器禁止 cookie 或不支持 cookie 怎么办?一般会把 sessionId 跟在 url 参数后面即重写 url,所以 session 不一定非得需要靠 cookie 实现
  • 移动端对 cookie 的支持不是很好,而 session 需要基于 cookie 实现,所以移动端常用的是 token

11.分布式架构下 session 共享方案

1. session 复制

  • 任何一个服务器上的 session 发生改变(增删改),该节点会把这个 session 的所有内容序列化,然后广播给所有其它节点,不管其他服务器需不需要 session ,以此来保证 session 同步

优点:可容错,各个服务器间 session 能够实时响应。

缺点:会对网络负荷造成一定压力,如果 session 量大的话可能会造成网络堵塞,拖慢服务器性能。

2. 粘性 session /IP 绑定策略

  • 采用 Ngnix 中的 ip_hash 机制,将某个 ip的所有请求都定向到同一台服务器上,即将用户与服务器绑定。用户第一次请求时,负载均衡器将用户的请求转发到了 A 服务器上,如果负载均衡器设置了粘性 session 的话,那么用户以后的每次请求都会转发到 A 服务器上,相当于把用户和 A 服务器粘到了一块,这就是粘性 session 机制。

优点:简单,不需要对 session 做任何处理。

缺点:缺乏容错性,如果当前访问的服务器发生故障,用户被转移到第二个服务器上时,他的 session 信息都将失效。

适用场景:发生故障对客户产生的影响较小;服务器发生故障是低概率事件。实现方式:以 Nginx 为例,在 upstream 模块配置 ip_hash 属性即可实现粘性 session。

3. session 共享(常用)

  • 使用分布式缓存方案比如 Memcached 、Redis 来缓存 session,但是要求 Memcached 或 Redis 必须是集群
  • 把 session 放到 Redis 中存储,虽然架构上变得复杂,并且需要多访问一次 Redis ,但是这种方案带来的好处也是很大的:
  • 实现了 session 共享;
  • 可以水平扩展(增加 Redis 服务器);
  • 服务器重启 session 不丢失(不过也要注意 session 在 Redis 中的刷新/失效机制);
  • 不仅可以跨服务器 session 共享,甚至可以跨平台(例如网页端和 APP 端)

session

4. session 持久化

  • 将 session 存储到数据库中,保证 session 的持久化

优点:服务器出现问题,session 不会丢失

缺点:如果网站的访问量很大,把 session 存储到数据库中,会对数据库造成很大压力,还需要增加额外的开销维护数据库。

只要关闭浏览器 ,session 真的就消失了?

不对。对 session 来说,除非程序通知服务器删除一个 session,否则服务器会一直保留,程序一般都是在用户做 log off 的时候发个指令去删除 session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭,因此服务器根本不会有机会知道浏览器已经关闭,之所以会有这种错觉,是大部分 session 机制都使用会话 cookie 来保存 session id,而关闭浏览器后这个 session id 就消失了,再次连接服务器时也就无法找到原来的 session。如果服务器设置的 cookie 被保存在硬盘上,或者使用某种手段改写浏览器发出的 HTTP 请求头,把原来的 session id 发送给服务器,则再次打开浏览器仍然能够打开原来的 session。恰恰是由于关闭浏览器不会导致 session 被删除,迫使服务器为 session 设置了一个失效时间,当距离客户端上一次使用 session 的时间超过这个失效时间时,服务器就认为客户端已经停止了活动,才会把 session 删除以节省存储空间。

12. 参考:

- https://www.cnblogs.com/woodk/p/10129836.html
    - 看源码的时候,可以画一下 主要模块的脑图,更有助于理解。
- https://www.cnblogs.com/longhao/p/3558871.html
- https://www.jianshu.com/p/8f4cc45d712e
- https://segmentfault.com/a/1190000013039187
- https://juejin.im/post/59d1f59bf265da06700b0934#heading-9
- https://juejin.im/post/5d01f82cf265da1b67210869#heading-11
点赞
收藏
评论区
推荐文章
Easter79 Easter79
4年前
springMVC笔记系列(8)——RequestParam注解
前面的文章介绍过注解@PathVariable,它能够为Rest风格的URL用占位符的方式传递一个参数,但是这个参数并不是真正意义上的请求参数。请求参数怎么处理是本文的主要内容。SpringMVC通过分析处理方法的签名,将HTTP请求信息绑定到处理方法的相应人参中。SpringMVC对控制器处理方法签名的限制是很宽松的,几乎可以按喜欢的任
东方客主 东方客主
4年前
Http请求头和请求响应头大全
HTTP响应头和请求头信息对照表HTTP请求头提供了关于请求,响应或者其他的发送实体的信息。HTTP的头信息包括通用头、请求头、响应头和实体头四个部分。每个头域由一个域名,冒号(:)和域值三部分组成。通用头标:即可用于请求,也可用于响应,是作为一个整体而不是特定资源与事务相关联。请求头标:允许客户端传递
徐小夕 徐小夕
4年前
深入浅出node中间件原理
前言中间件是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享、功能共享的目的。在NodeJS中,中间件主要是指封装http请求细节处理的方法。我们都知道在http请求中往往会涉及很多动作,如下:IP筛选查询字符串传递请求体解析cookie信息处理
Stella981 Stella981
4年前
Django中的session的使用
一、Session的概念cookie是在浏览器端保存键值对数据,而session是在服务器端保存键值对数据session的使用依赖cookie:在使用Session后,会在Cookie中存储一个sessionid的数据,每次请求时浏览器都会将这个数据发给服务器,服务器在接收到sess
Stella981 Stella981
4年前
Cookie,Session学习(java servlet编程)
Cookie问题:HTTP协议是没有记忆功能的,一次请求结束后,相关数据会被销毁。如果第二次的请求需要使用相同的请求数据怎么办呢?难道是让用户再次请求书写吗?为了解决这个问题,引入了Cookie技术;Cookie技术其实就是浏览器端实现的数据临时存储技术,保存一些必要的数据,当访问某些网页需要这些数据时,浏览器自动将数据加到HTTP请求
Stella981 Stella981
4年前
Python Requests 的一些高级特性
原文链接: PythonRequests的一些高级特性(https://my.oschina.net/ahaoboy/blog/1608447)会话对象会话对象让你能够跨请求保持某些参数。它也会在同一个Session实例发出的所有请求之间保持cookie,期间使用 urllib3 的 connectionpoolin
Stella981 Stella981
4年前
ActionContext和ServletActionContext区别以及action访问servlet API的三种方法
1\.ActionContext在Struts2开发中,除了将请求参数自动设置到Action的字段中,我们往往也需要在Action里直接获取请求(Request)或会话(Session)的一些信息,甚至需要直接对JavaServletHttp的请求(HttpServletRequest),响应(HttpServletResponse)操作.我们需要
Stella981 Stella981
4年前
Request学习笔记
Request请求对象:平时通过浏览器浏览网页的时候,浏览器会向服务器发送一些请求,而服务器则会把这些请求封装在HttpServletRequest中,我们可以通过这个对象获得一些用户的请求信息。Request.getParameter()是获取请求信息的重要API,或者Request.getParameterNames()。更多用法学习,具体可以查
Stella981 Stella981
4年前
SpringBoot整合SpringSeesion实现共享Session方案
Http协议本身是无状态的,为了保存会话信息,浏览器Cookie通过SessionID标识会话请求,服务器以SessionID为key来存储会话信息。在单实例应用中,可以考虑应用进程自身存储,随着应用体量的增长,需要横向扩容,多实例Session共享问题随之而来。下面假设我们使用Nginx来实现负载均衡横向扩节点:!(https://oscimg
Easter79 Easter79
4年前
SpringBoot整合SpringSeesion实现共享Session方案
Http协议本身是无状态的,为了保存会话信息,浏览器Cookie通过SessionID标识会话请求,服务器以SessionID为key来存储会话信息。在单实例应用中,可以考虑应用进程自身存储,随着应用体量的增长,需要横向扩容,多实例Session共享问题随之而来。下面假设我们使用Nginx来实现负载均衡横向扩节点:!(https://oscimg
3A网络 3A网络
3年前
一文读懂浏览器存储与缓存机制
一文读懂浏览器存储与缓存机制浏览器存储CookieCookie是HTTP协议的一种无状态协议。当请求服务器时,HTTP请求都需要携带Cookie,用来验证用户身份。Cookie由服务端生成,存储在客户端,用来维持状态。通常Cookie由以下值构成:名称(name)值(value)域(Domain)值(value)路径(Path)
安全客
安全客
Lv1
衣带渐宽终不悔,为伊消得人憔悴。
文章
3
粉丝
0
获赞
0