V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
wuhuaji
V2EX  ›  问与答

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

  •  
  •   wuhuaji · 2016-05-11 22:46:11 +08:00 · 2157 次点击
    这是一个创建于 3155 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    • 登录时,使用 cookie ,登录成功则设定一个已登录的 cookie ,例如: setcookie('login',true);然后跳转到主页或者其他页面中;同时在访问需要登录的页面时,则首先检测是否有相关的已登录 cookie ,没有则不让访问,或者跳转到登录。

    • 购物车中,用 session 来记住用户将哪些商品添加到购物车中,在结算时则从 session 中列出商品。

    那我这里有疑问:

    • 购物车中,显然 cookie 也能完成,(当然浏览器有 cookie 数限制),为何 session 更好呢?
    • 在延伸一下,我的问题主要是,虽说知道它们的区别,但是分不太清它们各自更适用的范围,也就是工程中的通用做法?也就是 [如何画马] 那副漫画中的最后一步:再添加其他细节就大功告成了

    还请各位指点一下 :)

    12 条回复    2016-05-12 18:15:18 +08:00
    murmur
        1
    murmur  
       2016-05-11 22:47:44 +08:00   ❤️ 1
    session 是服务器端, cookie 是浏览器端,显然 cookie 可以造假可以被破解
    session 的实现是依赖 cookie 里一个叫 JSessionID 之类长得特殊的值做到的
    当然如果没有 cookie 用 parameter 把他 传出去也可以要不 Oauth 咋实现的。。
    just1
        2
    just1  
       2016-05-11 22:48:16 +08:00 via Android
    错了吧,购物车用 cookie ,登录状态用 session 吧
    lightening
        3
    lightening  
       2016-05-11 22:49:02 +08:00   ❤️ 1
    Session 有许多实现方法, cookie 是其中一种。
    murmur
        4
    murmur  
       2016-05-11 22:50:00 +08:00
    购物车如果扔在 cookie 里是没问题的,而且可以实现离线购物车,未登录的用户他没有 UID 就可以存 cookie 里
    但是你想想购物车的数据很复杂啊,我如果想要这部分未注册用户的购物车数据呢,所以这部分数据存服务器,然后给离线用户分配一个临时 uid 扔 cookies 里也没什么。。
    还一个问题,购物车的数据很多,这部分放 cookies 里同域下是自动往服务器传的,我可不想每次呼啦传这么一大堆没用的数据
    murmur
        5
    murmur  
       2016-05-11 22:51:13 +08:00
    @just1 登录状态用 cookies 也是没问题的,告诉系统“我曾经来过”,但是不保证“现在用的是我”,这样可以个性化推给你广告,甚至可以不输密码让你看一下你商品是不是配送了,但是想看详情为了安全一般都是要输密码正式登录的
    murmur
        6
    murmur  
       2016-05-11 22:53:17 +08:00
    现在的教程用购物车当例子简直是 naive ,做过的表示购物车简直是天坑,离线购物车都是小 case ,真正的登录后合并购物车数据才是挖坑的开始,包括库存、活动、优惠、价格什么都要重新算一遍
    lightening
        7
    lightening  
       2016-05-11 23:06:57 +08:00   ❤️ 1
    因为 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
        8
    mornlight  
       2016-05-11 23:39:02 +08:00   ❤️ 1
    Cookie 是真正存在的一种东西, HTTP 协议里的,在 header 中。但 HTTP 协议里没有定义 session 这个概念,它是为了解决 HTTP 通信无状态的问题构造出的方案,很多场景下是利用 cookie 的特性来实现的。
    不要执念于这两者有什么区别和相似,而要知道他们不是同一种性质的概念。 session 很多时候被翻译成会话,你能指出我们日常生活中提到的会话,具体是什么吗?它更倾向于是描述一个过程和状态。 cookie 就不同了,我可以明确告诉你我发给你的请求头里 Cookie : 后面的一串字符是我这次要给你的 cookie 。
    常见的使用方式 7 楼已经说得够清楚了。
    wuhuaji
        9
    wuhuaji  
    OP
       2016-05-12 09:38:36 +08:00
    @murmur 对,你说的如果没有 cookie ,通过 parameter 也可以传递状态,这点我之前倒没有考虑到。
    如果把购物车放到 cookie 里,每次请求都发送 cookie 过去,确实是一种对资源的消耗。

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

    但是作为一个教程来说,上来就做完整购物车对学习者要求过高了。。所以能少复杂点就少复杂点
    lightening
        12
    lightening  
       2016-05-12 18:15:18 +08:00 via iPhone   ❤️ 1
    @wuhuaji cookie 是会保存下来的,你服务器端的数据也是会保存的,和关闭浏览器并没什么关系
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1077 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 22:45 · PVG 06:45 · LAX 14:45 · JFK 17:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.