一文读懂cookie,Session,Token,JWT之间的区别

1.什么是认证(Authentication)

通俗地讲就是验证当前用户的身份,证明“你是你自己”(比如:你每天上下班打卡,都需要通过指纹打卡,当你的指纹和系统里录入的指纹相匹配时,就打卡成功)。

互联网中的认证

用户名密码登录

邮箱发送登录链接

手机号接收验证码

只要你能收到邮箱/验证码,就默认你是账号的主人

 2.什么是授权(Authorization)

用户授予第三方应用访问该用户某些资源的权限。

你在安装手机应用的时候,APP 会询问是否允许授予权限(访问相册、地理位置等权	限)

你在访问微信小程序时,当登录时,小程序会询问是否允许授予权限(获取昵称、头像、地区、性别等个人信息)

实现授权的方式有:cookie、session、token、OAuth

3.什么是凭证(Credentials)

凭证是实现认证和授权的前提,是一种媒介(正数),用来标识访问者身份的方式。

在战国时期,商鞅变法,发明了照身帖。照身帖由官府发放,是一块打磨光滑细密的竹板,上面刻有持有人的头像和籍贯信息。国人必须持有,如若没有就被认为是黑户,或者间谍之类的。

在现实生活中,每个人都会有一张专属的居民身份证,是用于证明持有人身份的一种法定证件。通过身份证,我们可以办理手机卡/银行卡/个人贷款/交通出行等等,这就是认证的凭证。

在互联网应用中,一般网站(如掘金)会有两种模式,游客模式和登录模式。游客模式下,可以正常浏览网站上面的文章,一旦想要点赞/收藏/分享文章,就需要登录或者注册账号。当用户登录成功后,服务器会给该用户使用的浏览器颁发一个令牌(token),这个令牌用来表明你的身份,每次浏览器发送请求时会带上这个令牌,就可以使用游客模式下无法使用的功能。

会话管理

4.什么是cookie

4.1什么是无状态协议

百科解释:无状态协议是指比如客户获得一张网页之后关闭浏览器,然后再一次启动浏览器,再登录该网站,但是服务器并不知道客户关闭了一次浏览器。对于事务处理没有记忆能力,每次客户端和服务端会话完成时,服务端不会保存任何会话信息,即下一次链接不记住这一次链接的信息。

4.2.什么是有状态协议

通信双方要记住对方,用来共享信息。 个人理解是:记录了通信双方的信息。用一个不恰当的例子来说明,我是谁,我在哪里,我从哪里来,我要去哪里。

4.3.有状态协议和无状态协议的区别

协议的实现有没有要求客户端或者服务端需要维护一个状态。比如tcp传输需要经过握手来初始化事务(数据完整性的校验等),所以它是有状态的;显然http协议本身并没有要求这个,而cookie或session是浏览器和服务器在http协议之上,通过每次给本身并没有状态的请求中添加上某些约定的字段来实现的状态标记。HTTP利用浏览器的session和cookie来判断用户是处于登陆状态还是非登录状态,根据两种状态的不同,将不同的网页发送给浏览器。

机器中的“状态”可以理解为“记忆”,有状态对应有记忆,无状态对应无记忆。正常人是有记忆的,可以记住日常生活中的人和事,记忆存储在脑细胞中,这是有状态的。有些人犯了失忆症或者健忘症,无法记住曾经发生的事,脑海里一片空白,这就是无状态。

有状态协议就是就通信双方要记住双方,并且共享一些信息。而无状态协议的通信每次都是独立的,与你上一次的通信没什么关系。

用人话来说就是,你和朋友出去玩,不用每次都报上姓名联系方式等你朋友就知道你是谁,这就是有状态的;你去办事大厅,工作人员不会记得你是谁,每次都要填表、出示身份证,这就是无状态的。

理解了什么是无状态协议和有状态协议,下面的介绍就很容易明白了。

4.4.什么是 Cookie

HTTP是一种无状态协议:每个请求都是完全独立的,服务端无法确认当前访问者的身份信息,无法辨认上一次的请求发送者和这一次的是不是同一个人。服务器与浏览器为了进行会话跟踪(知道是谁在访问我),就必须主动去维护一个状态,这个状态用于告知服务器前后两个请求是否来自同一个浏览器。这个状态就是通过cookie和session来实现的。这样就达到了有状态的目的。cookie也是变量,也是用于存储键值对 , 和 session 非常像。

4.5.cookie存储在客户端

cookie是服务器发送到用户浏览器上并保存到本地的一小块数据,它会在浏览器下次向同一个服务器发送请求时被携带并发送至服务器上。服务器在接受到请求后, 可以从请求头中获取 cookie ,然后进行操作;把修改过的 cookie ,添加到响应中去 ,发送到客户端;客户端接受到响应的 cookie , 自动更新原有的cookie。cookie 是存放在 客户端上的 , 但是 服务器代码可以操作它 ,js代码也可以操作document.cookie 获取 cookie。

4.6.cookie是不可跨域的

每个cookie都会绑定单一的域名,无法再别的㥐下获取,一级域名和二级域名之间是允许共享的(靠的是domain)。

4.7.cookie 使用的场景
1) 记住我

2) 未登录的购物车

5.什么是Session

服务器端的应用程序通常是基于HTTP协议的,HTTP协议本身是一种“无状态”协议,所以,它并不能保存客户端的状态,例如,无法识别客户端的身份,所以,即使同一个客户端多次访问同一个服务器,服务器并不能识别出它就是此前来访的客户端!

在开发实践中,大多是需要能够识别客户端身份的,通常可以使用Session机制来解决!

当某个客户端首次访问某个服务器端时,将直接发起请求,当服务器端收到此请求时,会在响应时返回一个Session ID值(本质上是一个UUID值),当客户端收到Session ID后,后续的访问都会自动携带此Session ID到服务器端,则服务器端可以根据这个Session ID值来识别客户端的身份。

在服务器端,使用K-V结构的数据表示Session,客户端携带的Session ID就是K-V结构中的Key,所以,每个客户端都可以访问到不同的Value,即每个客户端对应的Session数据。

Session是存储在服务器端的内存中的数据,而内存资源是相对有限的资源,存储空间相对较小,所以,必然存在清除Session的机制,默认的清除机制是“超时自动清除”,即某个客户端最后一次提交请求之后,在多长时间之内没有再次提交请求,服务器端就会清除此客户端对应的Session数据!至于过多久清除Session,没有明确的要求,大多软件的默认时间是15~30分钟,但是,也可以设置为更短或更长的时间。

基于Session的特点,通常,存入到Session中的数据大多是:

  • 用户身份的标识,例如已登录的用户的ID

  • 访问频率较高的数据,例如已登录的用户的用户名

  • 不易于 / 不便于使用其它存储机制的数据,例如验证码

同时,Session还存在一些缺点:

  • 不适合存储大量的数据

    • 可以通过规范的开发避免此问题

  • 不易于应用到集群或分布式系统中

    • 可以通过共享Session解决此问题

  • 不可以长时间存储

    • 无解

  • 通过会话管理技术保存的是客户端和服务器之间的数据,而不是用户和服务器之间的数据

    • 会话管理保存的是和客户端相关的数据

    • 数据库保存的是和用户相关的数据

5.1.只要关闭浏览器 ,session 真的就消失了?

不对。对 session 来说,除非程序通知服务器删除一个 session,否则服务器会一直保留,程序一般都是在用户做 log off 的时候发个指令去删除 session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭,因此服务器根本不会有机会知道浏览器已经关闭,之所以会有这种错觉,是大部分 session 机制都使用会话 cookie 来保存 session id,而关闭浏览器后这个 session id 就消失了,再次连接服务器时也就无法找到原来的 session。

如果服务器设置的 cookie 被保存在硬盘上,或者使用某种手段改写浏览器发出的 HTTP 请求头,把原来的 session id 发送给服务器,则再次打开浏览器仍然能够打开原来的 session。恰恰是由于关闭浏览器不会导致 session 被删除,迫使服务器为 session 设置了一个失效时间,当距离客户端上一次使用 session 的时间超过这个失效时间时,服务器就认为客户端已经停止了活动,才会把 session 删除以节省存储空间。

6.Cookie和Session的区别?

Cookie: 数据保存在客户端(类似打孔会员卡)

  • 保存时间: Cookie默认保存在浏览器的内存中,当浏览器关闭数据会被清除, 也可以设置任意的保存时间,如果设置了保存时间,cookie数据会保存在客户端的磁盘中,当保存时间截止时会自动清除.

  • 数据类型: Cookie只能保存字符串数据

  • 应用场景: 主要应用在需要长时间保存数据的场景,比如:记住用户名和密码

Session:数据保存在服务器(类似银行卡)

  • 保存时间: 默认保存之间只有半个小时,由于所有客户端的数据都是保存在一个服务器的内存中,服务器的内存资源比较紧张,所以不能保存时间太久.

  • 数据类型: 可以保存任意对象类型的数据

  • 应用场景: 主要应用在对安全性要求较高的场景, 比如:登录状态

7.什么是Token(令牌)

Token:令牌,票据

Token机制是用于解决服务器端识别客户端身份的。

在使用Token机制时,当客户端首次向服务器提交请求时,或提交登录的请求时,客户端是直接将请求发送到服务器端的,并不做特殊处理,而服务器端会按需处理请求(例如客户端提交的是登录请求,则处理登录),并且将客户端的身份数据生成一个Token,并将此Token响应到客户端去,后续,客户端需要携带此Token提交各种请求,服务器端也会根据此Token数据来识别客户端的身份。

与Session不同,Token是由服务器端的程序(自行编写的)生成的数据,是一段有意义的数据,相比之下,Session机制中的Session ID是一个UUID值,仅保证唯一性,数据本身是没有意义的!Token不需要在服务器端存在匹配的数据,因为自身就是数据!

在处理过程中,服务器端只需要检查Token,并从Token中解析出客户端身份相关的数据即可,在服务器端的内存中并不需要保存Token的数据,所以,Token是可以设置较长甚至很长的有效期的,不会消耗服务器端用于存储数据的内存资源。

同时,Token天生就适用于集群或分布式系统,只需要各服务器具有相同的检查Token和解析Token的程序即可。

7.1.Acesss Token
访问资源接口(API)时所需要的资源凭证

简单 token 的组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,token 的前几位以哈希算法压缩成的
一定长度的十六进制字符串)

特点

服务端无状态化、可扩展性好

支持移动端设备

安全

支持跨程序调用

token 的身份验证流程:

客户端使用用户名跟密码请求登录

服务端收到请求,去验证用户名与密码

验证成功后,服务端会签发一个 token 并把这个 token 发送给客户端

客户端收到 token 以后,会把它存储起来,比如放在 cookie 里或者 localStorage 里

客户端每次向服务端请求资源的时候需要带着服务端签发的 token

服务端收到请求,然后去验证客户端请求里面带着的 token ,如果验证成功,就向客户端返回请求的数据

每一次请求都需要携带 token,需要把 token 放到 HTTP 的 Header 里

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

token 完全由应用管理,所以它可以避开同源策略
7.2.Refresh Token

另外一种 token——refresh token

refresh token 是专用于刷新 access token 的 token。如果没有 refresh token,也可以刷新 access token,但每次刷新都要用户输入登录用户名与密码,会很麻烦。有了 refresh token,可以减少这个麻烦,客户端直接用 refresh token 去更新 access token,无需用户进行额外的操作。

Access Token 的有效期比较短,当 Acesss Token 由于过期而失效时,使用 Refresh Token 就可以获取到新的 Token,如果 Refresh Token 也失效了,用户就只能重新登录了。

Refresh Token 及过期时间是存储在服务器的数据库中,只有在申请新的 Acesss Token 时才会验证,不会对业务接口响应时间造成影响,也不需要向 Session 一样一直保持在内存中以应对大量的请求。

8.Token 和 Session 的区别?

Session 是一种记录服务器和客户端会话状态的机制,使服务端有状态化,可以记录会话信息。而 Token 是令牌,访问资源接口(API)时所需要的资源凭证。Token 使服务端无状态化,不会存储会话信息。

Session 和 Token 并不矛盾,作为身份认证 Token 安全性比 Session 好,因为每一个请求都有签名还能防止监听以及重放攻击,而 Session 就必须依赖链路层来保障通讯安全了。如果你需要实现有状态的会话,仍然可以增加 Session 来在服务器端保存一些状态。

所谓 Session 认证只是简单的把 User 信息存储到 Session 里,因为 SessionID 的不可预测性,暂且认为是安全的。而 Token ,如果指的是 OAuth Token 或类似的机制的话,提供的是 认证 和 授权 ,认证是针对用户,授权是针对 App 。其目的是让某 App 有权利访问某用户的信息。

这里的 Token 是唯一的。不可以转移到其它 App上,也不可以转到其它用户上。Session 只提供一种简单的认证,即只要有此 SessionID ,即认为有此 User 的全部权利。是需要严格保密的,这个数据应该只保存在站方,不应该共享给其它网站或者第三方 App。

所以简单来说:如果你的用户数据可能需要和第三方共享,或者允许第三方调用 API 接口,用 Token 。如果永远只是自己的网站,自己的 App,用什么就无所谓了。

9.什么是JWT?

JWT:JSON Web Token

生成JWT的官网:JSON Web Tokens - jwt.io

每个JWT数据都是由3大部分组成的:

  • Header:声明算法与Token类型

  • Payload:数据

  • Verify Signature:验证签名

关于JWT编程的工具包:JSON Web Token Libraries - jwt.io

9.1.JWT的原理

JWT认证流程

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

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

当用户希望访问一个受保护的路由或者资源的时候,需要请求头的 Authorization 字段中使用Bearer 模式添加 JWT,其内容看起来是下面这样
9.2.Authorization: Bearer
服务端的保护路由将会检查请求头 Authorization 中的 JWT 信息,如果合法,则允许用户的行为

因为 JWT 是自包含的(内部包含了一些会话信息),因此减少了需要查询数据库的需要

因为 JWT 并不使用 Cookie 的,所以你可以使用任何域名提供你的 API 服务而不需要担心跨域资源共享问题(CORS)

因为用户的状态不再存储在服务端的内存中,所以这是一种无状态的认证机制
9.3.jwt的优点:
1.可扩展性好,应用程序分布式部署的情况下,session需要做多机数据共享,通常可以存在数据库或者redis里面。而jwt不需要。

2/无状态,jwt不在服务端存储任何状态。RESTful API的原则之一是无状态,发出请求时,总会返回带有参数的响应,不会产生附加影响。用户的认证状态引入这种附加影响,这破坏了这一原则。另外jwt的载荷中可以存储一些常用信息,用于交换信息,有效地使用 JWT,可以降低服务器查询数据库的次数。

3.json格式的通用性,所以JWT可以跨语言支持,比如Java、JavaScript、PHP、Node等等。

4.可以利用Payload存储一些非敏感的信息。

5.JWT结构简单,字节占用小,便于传输。

6.不需要在服务端保存会话信息,易于应用的扩展,特别适用于分布式微服务。
9.4.jwt的缺点:
1.安全性没法保证,所以 jwt 里不能存储敏感数据。因为 jwt 的 payload 并没有加密,只是用 Base64 编码而已。

2.法中途废弃。因为一旦签发了一个 jwt,在到期之前始终都是有效的,如果用户信息发生更新了,只能等旧的 jwt 过期后重新签发新的 jwt。

3.续签问题。当签发的 jwt 保存在客户端,客户端一直在操作页面,按道理应该一直为客户端续长有效时间,否则当 jwt有效期到了就会导致用户需要重新登录。那么怎么为 jwt 续签呢?最简单粗暴就是每次签发新的 jwt,但是由于过于暴力,会影响性能。如果要优雅一点,又要引入 Redis 解决,但是这又把无状态的 jw t硬生生变成了有状态的,违背了初衷。
10.Token 和 JWT 的区别?
相同:
都是访问资源的令牌

都可以记录用户的信息

都是使服务端无状态化

都是只有验证成功后,客户端才能访问服务端上受保护的资源
区别:
Token:服务端验证客户端发送过来的 Token 时,还需要查询数据库获取用户信息,然后验证 Token 是否有效。

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

基于session和基于jwt的方式的主要区别就是用户的状态保存的位置,session是保存在服务端的,而jwt是保存在客户端的.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zzyit

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值