请问何时使用 Cookie,何时使用 Session?

2016-05-11 22:46:11 +08:00
 wuhuaji

大多数教程都会使用登录和购物车来 解释 cookie 和 session :

那我这里有疑问:

还请各位指点一下 :)

2151 次点击
所在节点    问与答
12 条回复
murmur
2016-05-11 22:47:44 +08:00
session 是服务器端, cookie 是浏览器端,显然 cookie 可以造假可以被破解
session 的实现是依赖 cookie 里一个叫 JSessionID 之类长得特殊的值做到的
当然如果没有 cookie 用 parameter 把他 传出去也可以要不 Oauth 咋实现的。。
just1
2016-05-11 22:48:16 +08:00
错了吧,购物车用 cookie ,登录状态用 session 吧
lightening
2016-05-11 22:49:02 +08:00
Session 有许多实现方法, cookie 是其中一种。
murmur
2016-05-11 22:50:00 +08:00
购物车如果扔在 cookie 里是没问题的,而且可以实现离线购物车,未登录的用户他没有 UID 就可以存 cookie 里
但是你想想购物车的数据很复杂啊,我如果想要这部分未注册用户的购物车数据呢,所以这部分数据存服务器,然后给离线用户分配一个临时 uid 扔 cookies 里也没什么。。
还一个问题,购物车的数据很多,这部分放 cookies 里同域下是自动往服务器传的,我可不想每次呼啦传这么一大堆没用的数据
murmur
2016-05-11 22:51:13 +08:00
@just1 登录状态用 cookies 也是没问题的,告诉系统“我曾经来过”,但是不保证“现在用的是我”,这样可以个性化推给你广告,甚至可以不输密码让你看一下你商品是不是配送了,但是想看详情为了安全一般都是要输密码正式登录的
murmur
2016-05-11 22:53:17 +08:00
现在的教程用购物车当例子简直是 naive ,做过的表示购物车简直是天坑,离线购物车都是小 case ,真正的登录后合并购物车数据才是挖坑的开始,包括库存、活动、优惠、价格什么都要重新算一遍
lightening
2016-05-11 23:06:57 +08:00
因为 HTTP 是无状态的,所以为了在不同的 request 之间保存状态,需要 session 。直接翻译就是“会话”。

如果购物车数据是和用户 ID 相关的,可以做成数据库项。但是楼主也说了,一般购物车是不和用户 ID 关联的,而是和用户的浏览器关联。只要是同一个浏览器,就应该可以(暂时)保存购物车。那么就需要一种方法来在不同的 HTTP 请求之间保存数据。这个数据一般不要求 100% 可靠,万一丢了问题也不大。用户登录状态同理,这显然不是一个需要 persist 的数据库项,而是相对临时,并且只和用户的浏览器相关联。

几种实现方法:
1. 最常见的, cookie 。服务器有一个只有自己知道的秘钥,加密后丢给用户的浏览器。接到 request 时解开加密的 cookie ,获取存进去的数据。因为有加密,确保用户不能读取、篡改服务器存进去的数据。如果 session 里只有少量数据,不超过几百个字节,这个是最方便的。并且由于服务器不保存任何数据,这也是最容易 scale 的方法。即使我有几十台服务器做负载均衡也不用考虑同步 session 的问题。

2. 用 cookie 保存一个 session id ,然后服务器保存具体内容。如果 session 数据量很大,超过 cookie 4kb 的限制,那就只好这样了。能保存大量数据,但是不利于 scale 。一般用 redis 或 memcached 来保存,性能高点。

当然也可以两种方法组合起来用。
mornlight
2016-05-11 23:39:02 +08:00
Cookie 是真正存在的一种东西, HTTP 协议里的,在 header 中。但 HTTP 协议里没有定义 session 这个概念,它是为了解决 HTTP 通信无状态的问题构造出的方案,很多场景下是利用 cookie 的特性来实现的。
不要执念于这两者有什么区别和相似,而要知道他们不是同一种性质的概念。 session 很多时候被翻译成会话,你能指出我们日常生活中提到的会话,具体是什么吗?它更倾向于是描述一个过程和状态。 cookie 就不同了,我可以明确告诉你我发给你的请求头里 Cookie : 后面的一串字符是我这次要给你的 cookie 。
常见的使用方式 7 楼已经说得够清楚了。
wuhuaji
2016-05-12 09:38:36 +08:00
@murmur 对,你说的如果没有 cookie ,通过 parameter 也可以传递状态,这点我之前倒没有考虑到。
如果把购物车放到 cookie 里,每次请求都发送 cookie 过去,确实是一种对资源的消耗。

另外你说的用购物车用 session/cookie 来做是个坑,我之前也有一点考虑,想不清楚为什么很多教程用购物车解释 session ,更合理的做法显然是,添加到购物车时向数据库中插入数据,结算时再从数据库取出岂不是更好。
wuhuaji
2016-05-12 09:46:28 +08:00
@lightening 感谢回复,我这里还有个问题请教下: session 是当前浏览器和服务器之间的 [会话] ,那假如我浏览器关闭之后,这一次会话的生命周期就完了,下一次打开浏览器访问,则是一次新的会话,那么上一次会话的信息岂不是丢失了么? 不知道这么理解对不对?
murmur
2016-05-12 10:06:18 +08:00
@wuhuaji 我的个人倾向是即便是未注册用户的购物车也存在数据库,这是很重要的数据库,从系统设计的角度来看,当然是希望所有人都注册都使劲买到爆然后全部结账,但是为什么有些人添加了购物车最后却因为某些原因没有处理掉购物车,这部分数据是有分析价值的

但是作为一个教程来说,上来就做完整购物车对学习者要求过高了。。所以能少复杂点就少复杂点
lightening
2016-05-12 18:15:18 +08:00
@wuhuaji cookie 是会保存下来的,你服务器端的数据也是会保存的,和关闭浏览器并没什么关系

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/278033

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX