Cookie & Session & Token

本文介绍了Cookie、Session和Token的概念及其在Web开发中的作用。Cookie用于弥补HTTP协议无状态的特性,数据存储在客户端;Session数据存储在服务器端,依赖Cookie传递Session ID;Token,尤其是JWT,是一种无状态的认证机制,数据包含在Token中,可减少服务器查询数据库的次数。文中还探讨了Cookie、Session与Token的区别,并提及JWT的自包含性特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Cookie & Session & Token

Cookie:

理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。

而Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。(例:用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了)。要跟踪该会话,必须引入一种机制。

Cookie就是这样的一种机制。它可以弥补HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。

由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。

浏览器发起Http请求,服务器会进行Cookie设置,也就是Set-Cookie。Cookie里会包含名和值两个重要属性。

Cookie实际上是一小段的文本信息(存储在浏览器的数据)。客户端请求服务器,如果服务器需要记录该用户状态,服务器就会进行Cookie设置(也就是Set-Cookie),并把这个Cookie颁发给客户端浏览器。客户端浏览器会把Cookie保存起来。浏览器以后发送的每一个请求都会自动附上这个Cookie。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
在这里插入图片描述

Cookie具有不可跨域名性。 根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。

Session:

Session 是存放在服务器端的,类似于Session结构来存放用户数据,当浏览器 第一次发送请求时,服务器自动生成了一个Session和一个Session ID用来唯一标识这个Session,并将其通过响应发送到浏览器。当浏览器第二次发送请求,会将前一次服务器响应中的Session ID放在请求中一并发送到服务器上,服务器从请求中提取出Session ID,并和保存的所有Session ID进行对比,找到这个用户对应的Session。

一般情况下,服务器会在一定时间内(默认30分钟)保存这个 Session,过了时间限制,就会销毁这个Session。在销毁之前,程序员可以将用户的一些数据以Key和Value的形式暂时存放在这个Session中。当然,也有使用数据库将这个Session序列化后保存起来的,这样的好处是没了时间的限制,坏处是随着时间的增加,这个数据库会急速膨胀,特别是访问量增加的时候。一般还是采取前一种方式,以减轻服务器压力。

最常见的保存Session ID的方法是使用Cookie来保存。HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的Session ID(会话结束时间(Cookie的保存时间)也会传过去哦)。Session依据该Cookie来识别是否为同一用户。如果我们不设置过期时间,那么这个Cookie将不存放在硬盘上,当浏览器关闭的时候,Cookie就消失了,这个Session ID就丢失了。如果我们设置这个时间为若干天之后,那么这个Cookie会保存在客户端硬盘中,即使浏览器关闭,这个值仍然存在,下次访问相应网站时,同样会发送到服务器上,Cookie的有效期失效后,浏览器会自行删除这个Cookie。

在这里插入图片描述

cookie与session的区别:

cookie数据保存在客户端,session数据保存在服务器端。

Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端,用Cookie保存的,用户提交页面时,会将这一SessionID提交到服务器端,来存取Session数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用Cookie,那么Session也会失效。

cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗考虑到安全应当使用session。客户端每次请求服务器的时候会发送当前会话的session_id,服务器根据当前session_id判断相应的用户数据标志,以确定用户是否登录,或具有某种权限。由于数据是存储在服务器上面,所以你不能伪造,但是如果你能够获取某个登录用户的session_id,用特殊的浏览器伪造该用户的请求也是能够成功的。

session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用cookie。

单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。(Session对象没有对存储的数据量的限制,其中可以保存更为复杂的数据类型)

注意:

session很容易失效,用户体验很差;
虽然cookie不安全,但是可以加密 ;
cookie也分为永久和暂时存在的;(记住密码功能就是使用永久cookie写在客户端电脑,下次登录时,自动将cookie信息附加发送给服务端。)
浏览器有禁止cookie功能 ,但一般用户都不会设置;

两者最大的区别在于生存周期,一个是IE启动到IE关闭.(浏览器页面一关 ,session就消失了),一个是预先设置的生存周期,或永久的保存于本地的文件。(cookie)
(Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,Session依据该Cookie来识别是否为同一用户。该Cookie为服务器自动生成的,它的maxAge属性一般为-1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。)

Token:

token 也称作令牌,由uid+time+sign[+固定参数]组成

token 的认证方式类似于临时的证书签名, 并且是一种服务端无状态的认证方式, 非常适合于 REST API 的场景.所谓无状态就是服务端并不会保存身份认证相关的数据。

组成:

  • uid: 用户唯一身份标识
  • time: 当前时间的时间戳
  • sign: 签名, 使用 hash/encrypt压缩成定长的十六进制字符串,以防止第三方恶意拼接
  • 固定参数(可选): 将一些常用的固定参数加入到 token 中是为了避免重复查库

Token认证流程:
token 的认证流程与cookie很相似

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

在这里插入图片描述

token能放在cookie中吗?

token可以存放在Cookie中,token 是否过期,应该由后端来判断,不该前端来判断,所以token存储在cookie中只要不设置cookie的过期时间就ok了,如果 token 失效,就让后端在接口中返回固定的状态表示token 失效,需要重新登录,再重新登录的时候,重新设置 cookie 中的 token 就行。

JWT(Json Web Token)

jwt是目前最流行的跨域认证解决方案,是一种认证授权机制。

JWT 认证流程:

  • 用户输入用户名/密码登录,服务端认证成功后,会返回给客户端一个 JWT

  • 客户端将 token 保存到本地(通常使用 localstorage,也可以使用 cookie)

  • 当用户希望访问一个受保护的路由或者资源的时候,需要在请求头的 Authorization 字段中使用Bearer 模式添加 JWT,其内容看起来是下面这样:
    Authorization: Bearer

  • 服务端的保护路由将会检查请求头 Authorization 中的 JWT 信息,如果合法,则允许用户的行为

JWT 是自包含的(内部包含了一些会话信息),因此减少了需要查询数据库的需要
JWT 并不使用 Cookie,所以你可以使用任何域名提供你的 API 服务而不需要担心跨域资源共享问题(CORS)
因为用户的状态不再存储在服务端的内存中,所以这是一种无状态的认证机制

在这里插入图片描述

JWT由三部分组成:

  • header部分声明需要用什么算法来生成签名
  • payload部分是一些特定的数据

在这里插入图片描述

jwt保存在客户端,但是服务器端仍然保存一段密码,这段密码要结合两段编码(header和payload部分被编码)进行算法运算,最终得到签名信息。使用的算法就是header中声明的算法。

也就是说,token保存在用户端,服务器只保留密钥,每次请求服务器,都需要进行一次解密操作,解密后会拿出进行加密后的数据。

在这里插入图片描述

Token & JWT :

相同:

  • 都是访问资源的令牌
  • 都可以记录用户的信息
  • 都是使服务端无状态化
  • 都是只有验证成功后,客户端才能访问服务端上受保护的资源

区别:

  • Token:服务端验证客户端发送过来的 Token 时,还需要查询数据库获取用户信息,然后验证 Token 是否有效。

  • JWT:将 Token 和 Payload 加密后存储于客户端,服务端只需要使用密钥解密进行校验(校验也是 JWT 自己实现的)即可,不需要查询或者减少查询数据库,因为 JWT 自包含了用户信息和加密的数据。

session诞生并保存在服务器端,cookie是一种数据载体,把session id 放入cookie中传给客户端,随后cookie跟随http的每个请求发送出去。token是诞生在服务器但是保存在浏览器端的,可以放在cookie或storage中,持有有效token就可以访问服务器。

btw B站的技术蛋老师很值得关注!

代码、理论知识及图片绝大多数来自看过的博客&视频
俺只是加以整合并写了部分注释便于自己理解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值