session、cookie、token的区别

1.概述

我们都知道 HTTP 协议是无状态的,所谓的无状态就是客户端每次想要与服务端通信,都必须重新与服务端链接,意味着请求一次客户端和服务端就连接一次,下一次请求与上一次请求是没有关系的。

这种无状态的方式就会存在一个问题:如何判断两次请求的是同一个人?就好比用户在页面 A 发起请求获取个人信息,然后在另一个页面同样发起请求获取个人信息,我们如何确定这俩个请求是同一个人发的呢?

为了解决这种问题,我们就迫切需要一种方式知道发起请求的客户端是谁?此时,cookie、token、session 就出现了,它们就可以解决客户端标识的问题,在扩大一点就是解决权限问题。

它们就好比让每个客户端或者说登录用户有了自己的身份证,我们可以通过这个身份证确定发请求的是谁!

2.1 概念

Cookie 是一种在客户端存储数据的技术,它是由服务器发送给客户端的小型文本文件,存储在客户端的浏览器中,大小限制大致在 4KB 左右。在客户端发送请求时,浏览器会自动将相应的 Cookie 信息发送给服务器,服务器通过读取 Cookie 信息,就可以判断该请求来自哪个客户端。Cookie 可以用于存储用户的登录状态、购物车信息等。

在以前很多开发人员通常用 cookie 来存储各种数据,后来随着更多浏览器存储方案的出现,cookie 存储数据这种方式逐渐被取代,主要原因有如下:

1、cookie 有存储大小限制,4KB 左右。

2、浏览器每次请求会携带 cookie 在请求头中。

3、Cookie 本质存储的是字符串,若存储复杂或非 ASCII 数据,通常需要进行编码(如 URL Encode)。

4、数据可以被轻易查看。

2.2 cookie的主要属性

属性名 描述
name cookie 的名称
value cookie的值
commit cookie的描述信息
domain 可以访问该cookie的域名
expires cookie的过期时间,具体某一时间
maxAge cookie的过期时间
path cookie的使用路径
secure cookie是否使用安全协议传输,比如SSL等
version cookie使用的版本号
isHttpOnly 指定该 Cookie 无法通过 JavaScript 脚本拿到,比如 Document.cookie 属性、XMLHttpRequest 对象和 Request API 都拿不到该属性。这样就防止了该 Cookie 被脚本读到,只有浏览器发出 HTTP 请求时,才会带上该 Cookie。

2.3 cookie工作流程

  • 客户端发送请求到服务端(比如登录请求)。
  • 服务端收到请求后生成一个 session 会话。
  • 服务端响应客户端,并在响应头中设置 Set-Cookie。Set-Cookie 里面包含了 sessionId,它的格式如下:Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]。其中 sessionId 就是用来标识客户端的,类似于去饭店里面,服务员给你一个号牌,后续上菜通过这个号牌来判断上菜到哪里。
  • 客户端收到该请求后,如果服务器给了 Set-Cookie,那么下次浏览器就会在请求头中自动携带 cookie。
  • 客户端发送其它请求,自动携带了 cookie,cookie 中携带有用户信息等。
  • 服务端接收到请求,验证 cookie 信息,比如通过 sessionId 来判断是否存在会话,存在则正常响应。
  • cookie 存储在客户端
  • cookie 不可跨域,但是在如果设置了 domain,那么它们是可以在一级域名和二级域名之间共享的。

3. session

3.1 概念

session 由服务端创建,当一个请求发送到服务端时,服务器会检索该请求里面有没有包含 sessionId 标识,如果包含了 sessionId,则代表服务端已经和客户端创建过 session,然后就通过这个 sessionId 去查找真正的 session,如果没找到,则为客户端创建一个新的 session,并生成一个新的 sessionId 与 session 对应,然后在响应的时候将 sessionId 给客户端,通常是存储在 cookie 中。如果在请求中找到了真正的 session,验证通过,正常处理该请求。

每一个客户端与服务端连接,服务端都会为该客户端创建一个 session,并将 session 的唯一标识 sessionId 通过设置 Set-Cookie 头的方式响应给客户端,客户端将 sessionId 存到 cookie 中。

3.2 流程图

通常情况下,cookie 和 session 都是结合着来用,当然你也可以单独只使用 cookie 或者单独只使用 session,这里我们就将 cookie 和 session 结合着来用。如下图,具体流程介绍看上面cookie流程即可。

3.2 session与cookie的区别

  • cookie 和 session,它们两者之间主要是通过 sessionId 关联起来的,所以总结出:sessionId 是 cookie 和 session 之间的桥梁。

  • session 是基于 cookie 实现的,它们两个主要有以下特点:

  • session 比 cookie 更加安全,因为它是存在服务端的,cookie 是存在客户端的。

  • cookie 只支持存储字符串数据,session 可以存储任意数据。

  • cookie 的有效期可以设置较长时间,session 有效期都比较短。

  • session 存储空间很大,cookie 有限制。

系统想要实现鉴权,可以单独使用 cookie,也可以单独使用 session,但是建议结合两者使用。

4. token

4.1 概念

Token 是一种在客户端和服务端之间传递身份信息的方式。当用户登录成功后,服务端会生成一个 Token,将其发送给客户端。客户端在后续的请求中,需要将 Token 携带在请求头或请求参数中。服务端通过验证 Token 的合法性,就可以确定该请求来自哪个用户,并且可以根据用户的权限进行相应的操作。Token 可以有效地避免了 Cookie 的一些安全问题,比如 CSRF 攻击。

4.2 token的组成

Token是一个由一串字符组成的令牌,用于在计算机系统中进行身份验证和授权。它通常由三个部分组成:标头、有效载荷、签名。

标头(Header):包含了算法和类型,用于指定如何对有效载荷进行编码和签名。常用的算法有HMAC、RSA、SHA等。

有效载荷(Payload):包含了一些信息,如用户ID、角色、权限等,用于验证身份和授权。有效载荷可以是加密的,也可以是明文的。

签名(Signature):是对标头和有效载荷进行签名后得到的值,用于验证token的完整性和真实性。签名通常使用私钥进行签名,并使用公钥进行验证。

一个完整的token包含了标头、有效载荷和签名三个部分,它们一起构成了一个安全的令牌,用于进行身份验证和授权。

4.3 token认证流程

  • 客户端发起登录请求,比如用户输入用户名和密码后登录。
  • 服务端校验用户名和密码后,将用户 id 和一些其它信息进行加密,生成 token。
  • 服务端将 token 响应给客户端。
  • 客户端收到响应后将 token 存储下来。
  • 下一次发送请求后需要将 token 携带上,比如放在请求头中或者其它地方。
  • 服务端 token 后校验,校验通过则正常返回数据。

5. Cookie、session、token的区别

特点 优点 缺点
cookie 1.存储在客户端。 2.请求自动携带 cookie。 3.存储大小 4KB。 1.兼容性好,因为是比较老的技术。 2.很容易实现,因为 cookie 会自动携带和存储。 1.需要单独解决跨域携带问题,比如多台服务器如何共享 cookie。 2.会遭受 CSRF 攻击。 3.存储在客户端,不够安全。
session 1.存储在服务端。 2.存储大小无限制。 1.查询速度快,因为是个会话,相当于是在内存中操作。 2.结合 cookie 后很容易实现鉴权。 3.安全,因为存储在服务端。 1.耗费服务器资源,因为每个客户端都会创建 session。 2.占据存储空间,session 相当于存储了一个完整的用户信息。
Token 1.体积很小。 2.自由操作存储在哪里。 1.安全,因为 token 一般只有用户 id,就算被截取了也没什么用。 2.无需消耗服务器内存资源,它相当于只存了用户 id,session 相当于存储了用户的所有信息。 3.跨域处理较为方便,比如多台服务器之间可以共用一个 token。 1.查询速度慢,因为 token 只存了用户 id,每次需要去查询数据库。

注:使用token现在有了redis缓存中间件,不必频查数据库,查询一次后缓存使用

6.补充

问:cookie和session是不是都是由服务端产生呢?

Cookie 分两种(只有「服务器端 Cookie」由服务器产生,客户端 Cookie 可由浏览器前端生成);Session 确实是由服务器产生并存储的。

6.1 Cookie:分「服务器端生成」和「客户端生成」

Cookie 是存储在浏览器客户端的小型文本文件(键值对格式),它的产生来源有两个:

1. 服务器端生成

这是最常见的场景,流程如下:

  1. 客户端(浏览器)发送第一次请求(比如登录请求)到服务器;
  2. 服务器验证通过后,在响应头中添加 Set-Cookie 字段,携带 Cookie 信息(如会话标识、过期时间等);
  3. 浏览器接收到响应后,自动将 Set-Cookie 中的内容保存到本地(客户端);
  4. 后续客户端向该服务器发送请求时,会自动在请求头中携带对应的 Cookie,供服务器识别身份。

示例(HTTP 响应头中的 Set-Cookie)

复制代码
Set-Cookie: sessionid=123456abcdef; Path=/; Domain=xianjianai.com; Max-Age=3600

这种 Cookie 就是由服务器产生的,主要用于「身份识别、会话维持」(比如登录后保持登录状态),也是你在 Selenium/requests 中操作的核心 Cookie 类型。

2. 客户端生成(前端 JS 操作)

浏览器允许前端通过 JavaScript 直接创建 Cookie(存储在客户端),这种 Cookie 完全与服务器无关,仅在客户端生效。

示例(前端 JS 创建 Cookie)

javascript 复制代码
// 前端控制台执行,创建一个客户端 Cookie(服务器不会感知)
document.cookie = "username=test_user; expires=Fri, 31 Dec 2026 23:59:59 GMT; path=/";

浏览器允许前端通过 JavaScript 使用 document.cookie 创建 Cookie。

这类 Cookie 存储在客户端,但只要其 Domain 和 Path 与请求匹配,仍会在 HTTP 请求中自动发送给服务器

与服务器下发的 Cookie 相比,前端创建的 Cookie 无法设置 HttpOnly 属性,安全性较低,因此通常仅用于前端可控的非敏感数据。

6.2 Session:完全由服务器产生并存储

Session 通常称为「会话」,它的核心特点是由服务器产生、存储在服务器端,流程如下:

  1. 客户端第一次发送请求到服务器,服务器会创建一个唯一的 Session(包含会话 ID、会话数据、过期时间等);
  2. 服务器将 Session 的「唯一标识(Session ID)」通过「服务器端 Cookie」返回给客户端(即上面第一种 Cookie);
  3. 客户端后续请求时,会携带这个包含 Session ID 的 Cookie 到服务器;
  4. 服务器通过 Session ID 找到对应的 Session 数据,从而识别客户端身份、获取会话信息。
关键补充:
  1. Session 数据存储在服务器端(可以是内存、数据库、Redis 等),客户端仅存储「Session ID」(通过 Cookie 传递);
  2. Session 不能由客户端创建,因为它是服务器端的会话记录,客户端无法干预服务器的存储数据;
  3. 若客户端禁用 Cookie,服务器会通过「URL 重写」(将 Session ID 拼接在 URL 后)传递 Session ID,但这种方式安全性较低,现在很少使用。

6.3 核心区别总结(Cookie vs Session)

特性 Cookie Session
产生来源 服务器(核心)、客户端(前端JS) 仅服务器产生
存储位置 客户端(浏览器本地) 服务器端(内存/数据库/Redis等)
存储大小限制 有(单个 Cookie 通常 ≤ 4KB) 无(由服务器存储能力决定)
安全性 较低(存储在客户端,易被篡改) 较高(存储在服务器,仅暴露 Session ID)

总结

  1. Cookie 是浏览器的存储与传输机制,可以由服务器或客户端生成,只要域匹配就会随请求发送;
  2. Session 是服务器端的会话数据结构,只能由服务器创建和维护,客户端仅通过 Cookie 等方式携带 SessionID;
  3. HTTP 协议并不区分 Cookie 的创建来源,服务器只能看到浏览器最终发送的 Cookie 键值对。
相关推荐
JamesYoung79712 小时前
第一部分 — 基础知识 项目框架与文件布局
前端·chrome
nanbiandehe3 小时前
openclaw配置第三方api记录
chrome·ai编程·openclaw
JamesYoung79713 小时前
本书简介Chrome Manifest V3
chrome
L-李俊漩7 小时前
手机端的google chrome 浏览器 怎么看响应的日志和请求报文
前端·chrome·智能手机
武帝为此18 小时前
【Shell变量替换与测试】
前端·chrome
wsad05321 天前
Shell 脚本中的多行注释和 Here Document 语法解析
前端·chrome
Nanhuiyu2 天前
Shell编程从入门到精通-第二章 基础语法入门
chrome
REDcker3 天前
Media Source Extensions (MSE) 详解
前端·网络·chrome·浏览器·web·js
阿珊和她的猫3 天前
Chrome 的 SameSite 属性:原理与解决方案
前端·chrome
西门吹-禅4 天前
【iFlow 处理agents】
前端·chrome