我们先假设一个开发场景,我们要通过账号登录来记录不同的用户,该用户发表过哪些文章等等,但是我们要怎么来区分不同的用户账号呢?

一. cookie

这时就需要引入了我的 cookie , http 本是一个无状态的协议,但是在其请求头中加入 cookie,就使得我们的浏览器可以辨识不同的用户。第一次登录在后端匹配其用户账号密码登录成功后,在其响应头中为其设置 cookie 值, 将识别该用户的唯一值保存在 cookie 中,之后的每次请求都会在请求头中携带该值,可以标识用户。

  设置 Cookie 的所有参数值

res.setHeader('Set-Cookie', [key, value]) ;

有些同学会想,这不就相当于一个缓存吗,我也可以使用 localStorage 保存一个该用户身份,每次使用 POST 请求携带该身份也可以识别用户。确实如此可以实现同样的效果,但是变得复杂了很多。

首先每次请求需要使用 POST 请求 手动 携带该值,在服务器端每次获取该值要解析报文体,这就浪费了开销,并且该身份可以在前端人为修改,你就可以访问任何用户的任何信息,安全性很低。相比 cookie ,我们只需要设置一次,之后所有请求都会自动携带该值,但是 cookie 同样也可以在前端访问得到,也可以进行修改,因此单独用 cookie 来作为用户唯一识别也是不可行,其安全性也会受到威胁,我们只能用其保留一些其他不需要考虑安全性的数据。

cookie 性能问题:

由于 cookie 的实现机制,一旦服务器向客户端发送了设置 cookie 的意图,除非 cookie 过期,否则客户每次请求都会发送这些 cookie 到服务器,一旦设置 cookie 较多导致报头较大,因此需要优化其使用:

  • 减小 cookie 大小:如果在域名根节点设置 cookie,那么其所有子路径下的请求都会携带这些cookie,那么在不需要 cookie 的请求中携带 cookie 就显得那么多此一举了。
  • 为静态组件使用不同的域名:也就是说为不需要 cookie 的组件换个域名,可以降低cookie的无效传输

既然 cookie 不是最理想的标识用户的办法,那么我们就引入了 session 的使用。

二. session

cookie 虽然可以实现状态记录,但是并不是那么完美,为了解决 cookie 敏感数据问题, session 应运而生,由于 session 只保留在服务器端,客户端无法修改,这样数据的安全性就得到了保障。

  • 基于 cookie 来实现用户和数据的映射

        分析:将所有数据放在 cookie 中不可取,但是将口令放在 cookie 中还是可行的,在sessions 中存放 session,将 key 保存在 cookie 中, key 与 value 其映射关系放在sessions 中,一旦cookie 被更改,就失去了映射关系,需要重新获取 session。

① 生成 session

其中 key 是cookie 中保存口令的键值,用来存放 session.id ,来获取对应 session。

// 手动获取session
let createsession = function() {return {key: 's',  // 随意设置,对应的 cookie 保存口令get() {let session = {};session.id = (new Date()).getTime() + Math.random();session.cookie = {expire : (new Date()).getTime() + EXPIRES // EXPIRES 为过期时间}sessions[session.id] = session;return session;},isOverTime( session ) {return session.cookie.expire < (new Date()).getTime()}}
}();

②  设置 cookie

将生成的 session.id 设置为 cookie 值,在每次请求中携带。

let setSession = function(req, res) {let cookies = [];cookies.push(req.headers.cookie);let session = createsession.key+ '=' + req.session.id;cookies.push(session);res.setHeader('Set-Cookie', cookies);
}

③ 用来获取校验并获取session值

    let cookie = parseCookie(req.headers.cookie);console.log(cookie)let id = cookie[createsession.key];if(!id) { console.log('获取session') req.session = createsession.get();}else{console.log('有 session')let session = sessions[id];if( session ) {if(createsession.isOverTime(session)){// 过期console.log('过期')delete sessions[id];}else{// 更新时间console.log('更新过期时间')session.cookie.expire = (new Date()).getTime() + EXPIRES;req.session = session;}}else {console.log('重新获取session')//  session 过期或口令不对req.session = createsession.get();}}

④ 用 session 来存放信息

let handleEvent = function(req, res) {setSession(req, res);if(!req.session.user){req.session.user = '石头山';res.send('你好我叫石头山');}else{res.send('我知道你是' + req.session.user);}
}
  • 通过查询字符串来实现 session (感兴趣的可以自己查阅,因为应用不多不做解释)

这样我们就实现了在session中保存 数据,这种方法比在 Cookie 中直接保存安全很多,这种依赖Cookie 的实现是目前大多数 Web 使用方案。

session性能问题:

这种方式将 session 信息全部保存到服务器中,随着用户不断增多,可能很快会内存上限,并频繁检验 session 过期进行垃圾回收,严重影响性能,因此我们需要将 session 集中管理,目前常用的工具是 Redis,Memcached 等。

三. 总结

cookie 与 session 区别:

  • cookie 保存在服务器和前端中,而 session 只保存在服务器中

我们使用时,千万不要把 cookie 当成缓存使用,造成不必要的浪费,通过合理控制 session 的过期时间。

浅谈cookie 和 session【彻底弄明白】相关推荐

  1. JavaWeb|浅谈Cookie

    欢迎点击「算法与编程之美」↑关注我们! 本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章. 1 什么是Cookie Cookie,有时也用其复数形式 Co ...

  2. 浅谈cookie跨域的解决方案(domain)

    sso单点登录跨域cookie共享 首先了解cookie的两个属性 domain-域 通过设置这个属性可以使多个web服务器共享cookie.domain属性的默认值是创建cookie的服务器的主机名 ...

  3. 浅谈cookie跨域的解决方案——document.domain

    cookie的名/值对中的值不允许出现分号.逗号和空白符,因此在设置cookie前要用encodeURIComponent()编码,读取时再用decodeURIComponent()解码. cooki ...

  4. 浅谈Session与Cookie的关系

    阅读目录 一.概念理解: 首先cookie是服务端识别客户的唯一标识的依据,客户在访问网站时候,服务端为了记住这个客户,会在服务端按照它的规则制作一个cookie数据,会将这个cookie数据保留在服 ...

  5. 浅谈session,cookie,sessionStorage,localStorage的区别及应用场景

    浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式,可以利用cookie,session等跟服务端进行数据交互. 一.cookie和session cookie和session都是用来跟踪浏览器 ...

  6. 转载:浅谈Session与Cookie的区别与联系

    版权声明:本文为CSDN博主「dwl假行僧」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明. 原文链接:https://blog.csdn.net/duan107 ...

  7. 浅谈IM软件业务知识—会话session的概念,附一张IM软件的层次图

    ----------------------------------------------------欢迎查看IM软件业务知识<专栏>-------------------------- ...

  8. 浅谈ASP.NET的内部机制(一)

    浅谈ASP.NET的内部机制(一) 前言:当一个Http请求发送给一个aspx页面时,服务器进行了哪些操作?又如何来解析这个请求?ASP.NET在接收请求后是怎么运行的,如怎么编译以及怎么样用托管的代 ...

  9. 浅谈Python Web的五大框架

    说到web framework,Ruby的世界Rails一统江湖,而Python则是一个百花齐放的世界,各种micro-framework.framework不可胜数,不完全列表见:http://wi ...

最新文章

  1. NFS网络文件系统服务
  2. 江湖救急,换对姿势比《颈椎病康复指南》更有效丨极客官舍
  3. linux git中央仓库地址,如何在Linux上搭建一个Git中央仓库
  4. 参考:微软08财年产品路线图
  5. 小组会谈(2019.3.14)
  6. JavaScript | 数组的常用属性和方法
  7. 最短哈密尔顿圈matlab解法_复杂制造过程最优哈密尔顿圈算法的MATLAB仿真与分析.doc...
  8. sql语句循环截取字符串
  9. 系统性能评价的关键指标指标
  10. matlab绘制柱状图语句,matlab绘制柱状图
  11. 计算机专业学生组装电脑配置,我打算配置一台5000左右的组装台式电脑
  12. 入职Apifox研发组三个月,我领悟了30个高效开发方法
  13. VS Code 修改字体 + 取消注释斜体 + 修改注释颜色
  14. 中等专业学校计算机教师,中等专业学校计算机老师年度工作总结
  15. C语言中读取相对路径
  16. 桂花林上,再读“六项精进”
  17. 鼠标悬停之hover选择器
  18. HEARTS, CLUBS, DIAMONDS, SPADES: PLAYERS WHO SUIT MUDS
  19. fwrite函数,fread函数和fgets函数详解以及使用方法
  20. 使用c++代码打败红蜘蛛

热门文章

  1. js setCapture() releaseCapture() 获取页面上发生的所有的事件
  2. 【Linux】找不到ensss IP地址 或者连接不上ssh解决方法
  3. 怎么查dns服务器记录的请求信息,linux 查询dns服务器日志
  4. 解决TeamViewer可免费用于个人用途,但所使用的设备数量受限。您已达到设备数量上限
  5. 浅谈linux学习路线
  6. Bundle传值,判断某一对(k,v)是否存在
  7. windows双网卡配置路由三
  8. python waitpid_linux中waitpid及wait的用法
  9. 基于Kubernetes、Docker的机器学习微服务系统设计——完整版
  10. cf819C Jatayu‘s Balanced Bracket Sequence