共计 2598 个字符,预计需要花费 7 分钟才能阅读完成。
session,cookie 和 token 究竟是什么
简述
我在写之前看了很多篇 session,cookie 的文章,有的人说先有了 cookie,后有了 session。也有人说先有 session,后有 cookie。感觉都没有讲的很清楚,泛泛而谈。希望本篇文章对大家有所帮助注:本文需要读者有 cookie,session,token 的相关基础知识。
http 是一个无状态协议
什么是无状态呢?就是说这一次请求和上一次请求是没有任何关系的,互不认识的,没有关联的。这种无状态的的好处是快速。坏处是假如我们想要把 www.zhihu.com/login.html 和 www.zhihu.com/index.html 关联起来,必须使用某些手段和工具
cookie 和 session
由于 http 的无状态性,为了使某个域名下的所有网页能够共享某些数据,session 和 cookie 出现了。客户端访问服务器的流程如下
首先,客户端会发送一个 http 请求到服务器端。
服务器端接受客户端请求后,建立一个 session,并发送一个 http 响应到客户端,这个响应头,其中就包含 Set-Cookie 头部。该头部包含了 sessionId。Set-Cookie 格式如下,具体请看 Cookie 详解 Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]
在客户端发起的第二次请求,假如服务器给了 set-Cookie,浏览器会自动在请求头中添加 cookie
服务器接收请求,分解 cookie,验证信息,核对成功后返回 response 给客户端
注意
cookie 只是实现 session 的其中一种方案。虽然是最常用的,但并不是唯一的方法。禁用 cookie 后还有其他方法存储,比如放在 url 中
现在大多都是 Session + Cookie,但是只用 session 不用 cookie,或是只用 cookie,不用 session 在理论上都可以保持会话状态。可是实际中因为多种原因,一般不会单独使用
用 session 只需要在客户端保存一个 id,实际上大量数据都是保存在服务端。如果全部用 cookie,数据量大的时候客户端是没有那么多空间的。
如果只用 cookie 不用 session,那么账户信息全部保存在客户端,一旦被劫持,全部信息都会泄露。并且客户端数据量变大,网络传输的数据量也会变大
小结
简而言之, session 有如用户信息档案表, 里面包含了用户的认证信息和登录状态等信息. 而 cookie 就是用户通行证
token
token 也称作令牌,由 uid+time+sign[+ 固定参数]token 的认证方式类似于临时的证书签名, 并且是一种服务端无状态的认证方式, 非常适合于 REST API 的场景. 所谓无状态就是服务端并不会保存身份认证相关的数据。
组成
uid: 用户唯一身份标识
time: 当前时间的时间戳
sign: 签名, 使用 hash/encrypt 压缩成定长的十六进制字符串,以防止第三方恶意拼接
固定参数 (可选): 将一些常用的固定参数加入到 token 中是为了避免重复查库
存放
token 在客户端一般存放于 localStorage,cookie,或 sessionStorage 中。在服务器一般存于数据库中
token 认证流程
token 的认证流程与 cookie 很相似
用户登录,成功后服务器返回 Token 给客户端。
客户端收到数据后保存在客户端
客户端再次访问服务器,将 token 放入 headers 中
服务器端采用 filter 过滤器校验。校验成功则返回请求数据,校验失败则返回错误码
token 可以抵抗 csrf,cookie+session 不行
假如用户正在登陆银行网页,该网页未对 csrf 攻击进行防护。攻击者就可以注入一张图片,该图片 src 为 http://www.bank.com/api/transfer?count=1000&to=Tom。倘若是 session+cookie,用户打开网页的时候就已经转给 Tom1000 元了。因为 session 一旦建立,当前域页面以及该页面路径以下所有页面都共享 cookie。在 img 请求的瞬间,cookie 会被浏览器自动添加到请求头中。但 token 不同,开发者在每次发起请求时手动将 Token 添加到请求中。即打开页面请求 img 时,该请求头中没有 token
分布式情况下的 session 和 token
我们已经知道 session 时有状态的,一般存于服务器内存或硬盘中,当服务器采用分布式或集群时,session 就会面对负载均衡问题。
负载均衡多服务器的情况,不好确认当前用户是否登录,因为多服务器不共享 seesion。这个问题也可以将 session 存在一个服务器中来解决,但是就不能完全达到负载均衡的效果。当今的几种解决 session 负载均衡的方法。
而 token 是无状态的,token 字符串里就保存了所有的用户信息
客户端登陆传递信息给服务端,服务端收到后把用户信息加密(token)传给客户端,客户端将 token 存放于 localStroage 等容器中。客户端每次访问都传递 token,服务端解密 token,就知道这个用户是谁了。通过 cpu 加解密,服务端就不需要存储 session 占用存储空间,就很好的解决负载均衡多服务器的问题了。这个方法叫做 JWT(Json Web Token)
总结
session 存储于服务器,可以理解为一个状态列表,拥有一个唯一识别符号 sessionId,通常存放于 cookie 中。服务器收到 cookie 后解析出 sessionId,再去 session 列表中查找,才能找到相应 session。依赖 cookie
cookie 类似一个令牌,装有 sessionId,存储在客户端,浏览器通常会自动添加。
token 也类似一个令牌,无状态,用户信息都被加密到 token 中,服务器收到 token 后解密就可知道是哪个用户。需要开发者手动添加。
jwt 只是一个跨域认证的方案
参考文章
Cookie、Session、Token 那点事儿 cookie,token 验证的区别有了 cookie 为什么需要 sessionCSRF Token 的设计是否有其必要性 cookie,token,session 三者的问题和解决方案负载均衡集群中的 session 解决方案 JWT 介绍 Json Web Token 入门教程
谢谢
本文如有错误,欢迎留言讨论