深入理解 cookie,session,token

很多技术博客讲到 session,cookie 和 token 的区别和联系 ,但是介绍的不够清晰,因此参考了一些博客,在这里总结记录一下。

众所周知,HTTP 是一种无状态协议,即每次客户端发送请求时,对于服务端来说接收到的都是一个全新的请求,因此服务器并不知道客户端的历史请求记录。

比如不同的用户登录退出一个网站,每个人的会话状态都是不同的,所以网站需要对这些会话进行管理,而我们今天要讨论的 cookie,session, token 就是用来管理会话的手段。


1. cookie

cookie 是什么

cookie 是浏览器里面能永久存储的一种数据,是浏览器实现的一种数据存储功能。

cookie 有什么用

因为 HTTP 协议是无状态的,服务器无法记录用户上一次的操作,会造成交互上的阻碍。而 cookie 则可以做到绕开 HTTP 的无状态,也就是服务器可以从 cookie 中读取包含的信息,来维护用户和服务器会话中的状态(比如购物 / 登录)。

cookie 有什么特点

  • cookie 存储在客户端:cookie是由服务器生成后发送到客户端的,客户端以 key-value 形式将数据保存在本地,在下次请求同一网站时会把该 cookie 发送给服务端。

  • cookie为不可跨域的:每个 cookie 都会绑定单一的域名,无法在别的域名下获取和使用,不过一级域名和二级域名之间是允许共享使用的。

cookie 中的参数说明

参数 说明 后端调用
Domain 指定 cookie 所属域名,默认是当前域名 cookie.setDomain("")
Max-Age 设置cookie的过期时间,单位为秒 cookie.setMaxAge(10)
Path 指定 cookie 在哪个路径(路由)下生效,默认是 ‘/’ cookie.setPath("/")
HttpOnly 如果给某个 cookie 设置了 httpOnly 属性,则无法通过 JS 脚本读取到该 cookie 的信息,但还是能通过 Application 中手动修改 cookie,所以只是一定程度上可以防止 XSS 攻击,不是绝对的安全 cookie.setHttpOnly(true)
Secure 告诉浏览器此 cookie 只能在 HTTPS 安全协议中传输,如果是 HTTP 则禁止传输 cookie.setSecure(true)

cookie 的局限性

  • cookie 必须在 HTML 文件的内容输出前进行设置;

  • 不同的浏览器对 cookie 的处理不一致,使用时一定要注意;

  • 客户端用户如果设置禁用 cookie,则 cookie 不能建立;

  • 每个客户端浏览器可创建的 cookie 数量最多为 300 个,并且每个不能超过 4KB,每个 Web 站点能设置的 cookie 总数不能超过 20 个;

HTTP 的传输有一个很大的问题,就是明文传输。那么,明文传输会导致什么问题呢?

意味着我可以抓包来获取用户信息(比如使用 WireShark \ Fiddle 等工具),而且 HTTP 请求是可以篡改的,且篡改难度很低。同时,根据客户端信息不可靠原则,我们需要一个东西来验证用户的身份,此时就轮到 session 出场了。


2. session

session 是什么

session 是一种抽象的概念,开发者为了实现中断和继续等操作,将 user agent 和 server 之间一对一的交互抽象为 “会话”,进而衍生出 “会话状态”

session 有什么用

服务端为每个用户生成不同的身份标识 session id,还有与之相对应的信息,比如用户 id 和登录时间等。通过服务端的 session 和浏览器的cookie 一一对应,来区分用户身份。

session 有什么特点

  • cookie 是一个实际存在的东西,是 http 协议中定义在 header 中的字段,而 session 只是一种 cookie 的后端无状态实现
  • session 是基于 cookie 实现的,它存储在服务器端,可以理解为一个状态列表,拥有一个唯一识别符号 sessionId,通常存放于 cookie 中;
  • 移动端对 cookie 的支持不是很好,而 session 需要基于 cookie 实现,所以移动端常用的是 token;

session 的工作流程

浏览器访问服务器的流程如下:
在这里插入图片描述

  1. 浏览器发送一个 http 请求到服务器端。

  2. 服务端接收请求后,创建对应的 session ,并发送一个 http 响应到客户端,这个响应的响应头中包含了 sessionId

  3. 浏览器接收到服务端返回的 sessionId 后,将此信息存入 cookie ,同时 cookie 记录此 sessionId 属于哪个域名;

  4. 当用户第二次发起请求时,请求会自动判断此域名下是否存在 cookie 信息,如果存在,浏览器会自动在请求头中添加 cookie 并发送到服务端;

  5. 服务端接收请求,会从 cookie 中获取 sessionId,再根据 sessionId 查找对应的 session 信息,如果没有找到,则说明用户没有登录或者登录失效;如果找到了,则证明用户已经登录,可继续执行后面的操作。


3. token

token 是什么

token 的意思是 “令牌” ,是用户身份的验证方式,简单的 token 组成为:uid (用户唯一的身份标识)、time (当前时间的时间戳)、sign(签名,token 的前几位以哈希算法压缩成的一定长度的十六进制字符串),相当于上文提到的 session id

token 有什么用

token 的用户认证是一种服务端无状态的认证方式,所以用解析 token 的计算时间可以换取 session 的存储空间,从而来减轻服务器的压力,减少对数据库的频繁查询。

同时,token 可以抵抗 csrf,具有更高的安全性。

token 有什么特点

  • cookie + session 不能抵抗 csrf,但是 token 可以,因为浏览器不会自动把 token 添加到headers 里,攻击者也无法访问用户的 token,所以提交的表单无法通过服务器过滤,也就无法形成攻击;
  • token 的认证方式类似于临时的证书签名, 并且是一种服务端无状态的认证方式, 所谓无状态就是服务端并不会保存身份认证相关的数据,非常适合于 REST API 的场景。
  • cookie 和 session 有自动过期的设置,而 token 的状态和过期时间需要自己手动设置。比如说,token中存储用户登录的时间,服务端每次收到请求后,都需要去验证这个时间是否过期。

token 认证流程

在这里插入图片描述

  1. 客户端使用用户名和密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端签发一个 token ,并把它发送给客户端
  4. 客户端接收 token 以后会把它存储起来,比如放在 cookie 里或者 localStorage 里
  5. 客户端每次发送请求时都需要带着服务端签发的 token(把 token 放到 HTTP 的 Header 里
  6. 服务端收到请求后,需要验证请求里的 token ,如验证成功则返回对应的数据

欢迎关注我的公众号,用讲故事的方式学技术。

这里有脑洞大开的奇葩故事,也有温暖文艺的心灵感悟。

技术知识,也可以很有趣。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/j1231230/article/details/112918236
今日推荐