Cookie、Session、Token 的区别与用途
Cookie、Session、Token 的区别与用途
Cookie
Cookie 是由服务器发送到用户浏览器并存储在用户计算机上的小型文本文件。它包含有关用户的信息,如用户ID、密码、浏览记录等。当用户再次访问网站时,浏览器会将Cookie信息发送回服务器,帮助服务器识别用户身份。
服务器传回的响应头中的 Set-Cookie 里就是传回的 Cookie,浏览器解析响应头时,会自动将 Set-Cookie 的内容作为 Cookie 保存在本地,后续的 HTTP 请求都会带上 Cookie。
我们打开浏览器,是可以看到 Cookie 的内容的,而且因为是明文传输,所以在 Cookie 中存用户名和密码是非常不安全的行为。
Session
Session 是服务器为每个用户创建的一个临时会话对象。它包含有关用户会话的信息,例如用户ID、登录状态等。Session通过在服务器上存储用户数据,可以跟踪用户的操作,从而实现用户认证和个性化服务。与Cookie不同,Session不存储在用户的计算机上,而是在服务器上。
Session 在两种情况下会自动销毁:
- 客户端关闭浏览器程序
- Session 超时(会话超时):客户端一段时间内没有访问过该Session内存,服务器会清理。回话超时的时间,默认是30分钟,只要发起请求,会话时间从0重新计算。
Cookie 和 Session 的区别
- cookie 数据存放在浏览器上,服务器能够知道其中的信息。session 数据会在一定时间内保存在服务器上,客户端不知道其中的信息,当访问增多,会比较消耗服务器的性能。
- cookie 不是很安全,别人可以分析存放在本地的 cookie 并进行 cookie 欺骗。session 相对安全,建议将登录信息等重要信息存放为 session。其他信息如果需要保留,可以放在cookie中。
- 单个 cookie 保存的数据不能超过4KB,很多浏览器都限制一个站点最多保存20个 cookie。session 容量更大,可以保存对象。
- session 中保存的是对象,cookie 中保存的是字符串。
- session 不能区分路径,同一个用户在访问一个网站期间,所有的 session 在任何一个地方都可以访问到。cookie 中如果设置了路径参数,同一个网站中不同路径下的 cookie 互相是访问不到的。
Token
为什么要用 Token?
基于服务器的验证:
HTTP 是无状态的,这种无状态意味着程序需要验证每一次请求,从而辨别客户端的身份。在这之前,程序都是通过在服务端存储的登录信息来辨别请求的。这种方式一般都是通过存储 Session 来完成。随着 web应用程序,以及移动端的兴起,这种验证的方式逐渐暴露出了问题。尤其是在可扩展性方面。
基于服务器验证方式暴露的一些问题:
- 每一个用户都需要一个 Session,而服务器要保存所有人的 session id。如果用户量很大,就要有大量的 session id 存储在服务器中。这对服务器说是一个巨大的开销,严重的限制了服务器扩展能力。
- 可扩展性:在服务端的内存中使用 Seesion 存储登录信息,伴随而来的是可扩展性问题。
- 如果服务器集群采用均衡负载的方法,用户访问服务器时,Session 会在服务器之间复制转发;也可以将 Session 存储在数据库中,服务器每次从服务器取 Session 来验证,这些做法都比较麻烦。
- CORS(跨域资源共享):基于 Cookie 的 Session 不能跨域,同一用户通过网页、手机访问同一页面,自身端口是不同的,每次访问的服务器端口也可能不同。需要在后端设置允许跨域,还需要在前端单独设置允许跨域的 Cookie 传递,非常麻烦。
- CSRF(跨站请求伪造):如果黑客获取到用户的 Cookie,可以冒充用户访问网站,存在风险。
在这些问题中,可扩展性是最突出的。因此有必要去寻求一种更行之有效的方法。
基于 Token 的验证原理
基于 Token 的身份验证是无状态的,无需将用户信息存在服务器或 Session 中。这种概念解决了在服务端存储信息时的许多问题。NoSession 意味着程序可以根据需要去增减机器,而不用去担心用户是否登录。
基于 Token 的身份验证的过程如下:
- 用户通过用户名和密码发送请求。
- 服务器做登录校验,校验成功后就返回 Token 给客户端。
- 客户端储存 Token,并且用于每次发送请求。
- 服务器端采用 filter 过滤器校验。校验成功则返回请求数据,校验失败则返回错误码。
可以看出,Token 由服务器生成,但存储在客户端的 Cookie 或者 Storage 里面。
Token 如何生成?
JWT(Json Web Token)是一种可以跨域的认证方案。它由三部分构成:
- 头部(Header):头部包含了两部分,token 类型和采用的加密算法(可为none,后端应限制加密算法,不以这里为准,一般采用 HMAC-SHA256 算法)。
- 载荷(Payload):这部分才是重要的,可以自定义信息保存在此。
- 签名(Signature):使用编码后的header和payload以及我们提供的一个密钥,然后使用header中指定的签名算法进行签名。签名的作用是保证JWT没有被篡改过,如果有人对头部以及负载的内容解码之后进行修改,再进行编码,最后加上之前的签名组合形成新的JWT的话,那么服务器端会判断出新的头部和负载形成的签名和JWT附带上的签名是不一样的。如果要对新的头部和负载进行签名,在不知道服务器加密时用的密钥的话,得出来的签名也是不一样的。
这三部分均用 Base64 进行编码,并使用 . 进行分隔。一个典型的 JWT 格式的 token 类似xxxxx.yyyyy.zzzzz。
Base64 是可逆的,所以注意在Payload部分不要携带敏感信息。
Token 的优势
- 无状态:在客户端存储的 Tokens 是无状态的,且不存储 Session 信息。基于此,负载均衡器能够将用户信息从一个服务传到其他服务器上。
- 简洁 : 可以通过URL,POST参数或者在HTTP header发送,因为数据量小,传输速度也很快。
- 自包含(Self-contained):负载中包含了所有用户所需要的信息,避免了多次查询数据库。
- 安全性:请求中发送 token 而不再是发送 cookie 能够防止 CSRF(跨站请求伪造)。即使在客户端使用 cookie 存储 token,cookie 也仅仅是一个存储机制而不是用于认证。
- 可扩展性:Tokens 能够创建与其它程序共享权限的程序。使用tokens时,可以提供可选的权限给第三方应用程序。当用户想让另一个应用程序访问它们的数据,服务器可以通过建立自己的API,得出特殊权限的tokens。
- 多平台跨域:对应用程序和服务进行扩展的时候,需要介入各种各种的设备和应用程序。只要用户有一个通过了验证的 token,数据和资源就能够在任何域上被请求到。
Cookie、Session、Token 的用途
假设我们正在开发一个博客平台,用户可以注册、登录并发表文章。在这个案例中,我们需要解决以下几个问题:
- 如何让用户在多个请求之间保持一致的身份?
- 如何确保用户数据的安全传输?
- 如何避免跨域问题?
针对这些问题,我们可以分别采用 Cookie、Session 和 Token 技术进行解决。以下是具体实施方案。
使用 Cookie 保存用户偏好:当用户登录博客平台时,服务器会生成一个唯一的 Session ID,并将其存储在 Cookie 中。后续的请求中,客户端携带 Session ID,服务器通过 Session ID 查找对应的 Session 信息来验证用户身份。此外,我们还可以利用 Cookie 保存用户的偏好设置,如主题、语言等。
使用 Session 进行数据会话:在用户登录后,服务器会为该用户创建一个 Session,其中包含用户的用户名、权限等信息。Session 用于保存用户在一段时间内的操作数据,如编辑文章、发表评论等。通过这种方式,我们可以确保用户数据的安全传输。
使用 Token 进行身份验证和跨域认证:服务器生成一个 Token 并返回给客户端。在后续的请求中,客户端需要将 Token 带上,服务器通过验证 Token 来确定该请求是否合法。这样,我们就可以解决跨域问题,同时确保只有持有有效 Token 的用户才能访问平台。
通过以上方案,我们成功解决了博客平台中的身份验证和数据传输问题。在这个案例中,Cookie、Session 和 Token 各自发挥了重要作用,确保了用户身份的一致性、数据安全性以及跨域问题的解决。然而,它们之间仍存在区别:
-
Cookie 主要应用于客户端存储和个性化设置,如用户偏好、登录状态等。
-
Session 则侧重于服务器端保存用户状态和权限控制,可在多个请求之间保持用户身份一致。
-
Token 则用于身份验证和授权,可解决跨域问题,并确保请求的合法性。
在实际开发中,这些技术通常会结合使用,以实现更安全、高效的身份验证和数据管理。通过充分了解 Cookie、Session 和 Token 的区别,我们可以根据项目需求选择合适的技术,确保用户身份安全和数据传输效率。
参考
- https://blog.youkuaiyun.com/ChineseSoftware/article/details/122999009
- https://www.bilibili.com/video/BV1ob4y1Y7Ep
- https://www.bilibili.com/video/BV1at421G7YC
- https://blog.youkuaiyun.com/wingrant/article/details/126445880
- https://blog.youkuaiyun.com/qq_54850598/article/details/127672246