Jwt,Token,Cookie,Session之间的区别

思维导图

image

1.基本概述

2.1认证(Authentication)

认证是关于验证你的凭据,如用户名/邮箱和密码,以验证访问者的身份。系统确定你是否就是你所说的使用凭据。在公共和专用网络中,系统通过登录密码验证用户身份。身份认证通常通过用户名和密码完成,有时与认证可以不仅仅通过密码的形式,也可以通过手机验证码或者生物特征等其他因素。

在某些应用系统中,为了追求更高的安全性,往往会要求多种认证因素叠加使用,这就是我们经常说的多因素认证。

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

常见的认证方式:

  • 用户名密码认证
  • 手机和短信验证码认证
  • 邮箱和邮件验证码认证
  • 人脸识别/指纹识别的生物因素认证
  • OTP 认证
  • Radius 网络认证

2.2授权(Authorization)

授权发生在系统完成身份认证之后,最终会授予你访问资源(如信息,文件,数据库,资金,位置,几乎任何内容)的完全权限。简单来说,授权决定了你访问系统的能力以及达到的程度。

授权是确定经过身份验证的用户是否可以访问特定资源的过程。它验证你是否有权授予你访问信息,数据库,文件等资源的权限。授权通常在验证后确认你的权限。简单来说,就像给予某人官方许可做某事或任何事情。

例如,验证和确认组织中的邮箱和密码的过程称为认证,但确定哪个员工可以访问哪个楼层称为授权。假设你正在旅行而且即将登机。当你在登记前出示机票和一些身份证明时,你会收到一张登机牌,证明机场管理局已对你的身份进行了身份验证。但那不是它。乘务员必须授权你登上你应该乘坐的航班,让你可以进入飞机内部及其资源。

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

  • 你在安装手机应用的时候,APP 会询问是否允许授予权限(访问相册、地理位置等权限)
  • 你在访问微信小程序时,当登录时,小程序会询问是否允许授予权限(获取昵称、头像、地区、性别等个人信息)

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

2.3认证与授权的对比

认证

授权

验证确认身份以授予对系统的访问权限。

授权确定你是否有权访问资源。

这是验证用户凭据以获得用户访问权限的过程。

这是验证是否允许访问的过程。

它决定用户是否是他声称的用户。

它确定用户可以访问和不访问的内容。

身份验证通常需要用户名和密码。

授权所需的身份验证因素可能有所不同,具体取决于安全级别。

身份验证是授权的第一步,因此始终是第一步。

授权在成功验证后完成。

例如,特定大学的学生在访问大学官方网站的学生链接之前需要进行身份验证。这称为身份验证。

例如,授权确定成功验证后学生有权在大学网站上访问哪些信息。

2.4凭证(Credentials)

  • 实现认证和授权的前提
  • 是需要一种媒介(证书)来标记访问者的身份

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

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

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

2.5认证、授权、确权与鉴权

概念

说明

认证

确认声明者的身份。

授权

获取用户的委派权限。

确权

用户对授权进行确认。

鉴权

对所声明的权限真实性进行鉴别的过程。

2.Cookie

2.1Cookie概述

HTTP是无状态的协议:每个请求都是完全独立的,服务端无法确认当前访问者的身份信息,无法分辨上一次的请求发送者和这一次请求的发送者是不是同一个客户端。服务器与浏览器为了进行会话跟踪,就必须主动的去维护一个状态,这个状态用于告诉服务端前后两个请求是否来自同一个浏览器。这个状态就需要通过cookie或者session来实现。(简单来说我们需要有一个标记让浏览器认识我们,当我们第一次登录之后保存我们的登录信息,方便下次登录。)

cookie存储在客户端cookie是服务器发送到用户浏览器,并进行保存到本地的数据,它会在浏览器下次向同一服务器再发起请求时被再一次被带到并发送到服务器上面

cookie是不可跨域名的:每个cookie都会绑定单一的域名,无法在别的域名下获取使用。

先明确一点,Cookie 就是为了解决 HTTP 协议无状态的问题,接下来举个例子说明。

早年间医院对患者的病例还没有在线建档的时候,都需要患者在就医之前,办理一个病历的小册子,医生会在病历中写上此次就医的情况,什么时间、有什么表现的反映、诊断是什么病、开了一些什么药等等。如果下次又生病了,有病历的情况下,都会要求患者再把病历带上,这样医生就能通过病历了解到之前的情况。

Cookie 的实现上,也是这样的。

服务端(医生)在收到客户端(患者)请求的时候,将一些用户标识信息加入到 Cookie (病例)中,随着响应返回给客户端,客户端将 Cookie 中的信息存储在本地,下次再请求此服务器的时候,再将 Cookie 中携带的数据原样传输给服务端,此时服务端就能通过 Cookie 中的用户标识,识别出这是之前请求过的某个用户。

在这个例子中,服务端就是医生的角色、客户端是患者的角色、Cookie 就是病历。

cookie 重要的属性:

image

2.2一个完整的cookie细节

HTTP 协议中的规则,都是通过在请求头和响应头中写入输入来实现,Cookie 也是这样的。

服务端通过 Set-Cookie 这个响应头来向客户端中写入 Cookie 信息,而客户端读取 Set-Cookie 这个响应头中的信息存储起来,在下次请求的时候取出来,再通过 Cookie 这个请求头,将 Cookie 的数据传输给服务端。

再看一个浏览器中,Cookie 使用的实例。

在响应头**(Response Header)**中,使用 Set-Cookie 传递不同的 Cookie 数据,多个数据可以分开成多个 Set-Cookie 头。

在请求头中**(Request Header)**中,使用 Cookie 这个请求头传递 Cookie 数据,不同的数据通过 ;分割。

2.2Set-Cookie 和 Cookie 标头

Set-Cookie HTTP 响应标头将 cookie 从服务器发送到用户代理。下面是一个发送 Cookie 的例子

image

有两种类型的 Cookies,一种是 Session Cookies会话 cookie,一种是 Persistent Cookies永久 cookie,如果 Cookie 不包含到期日期,则将其视为会话 Cookie。会话 Cookie 存储在内存中,永远不会写入磁盘,当浏览器关闭时,此后 Cookie 将永久丢失。如果 Cookie 包含有效期 ,则将其视为持久性 Cookie。在到期指定的日期,Cookie 将从磁盘中删除。

还有一种是 Cookie 的 SecureHttpOnly 标记。

2.3永久性Cookie

永久性 Cookie 不会在客户端关闭时过期,而是在特定日期(Expires)特定时间长度(Max-Age)外过期。例如

代码语言:javascript
复制
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2023 07:28:00 GMT;

永久性 Cookie 主要用于实现一些持久性的记住用户偏好设置、登录状态等功能。当用户再次访问该网站时,可以根据存储在永久性 Cookie 中的信息来恢复用户的个性化设置,提供更好的用户体验。同时,该类型的 Cookie 也常被用于追踪用户行为、广告定向等目的。

2.5Cookie 的作用域

3.Session

3.1Session概述

Session 是客户端与服务器通讯会话跟踪技术,服务器与客户端保持整个通讯的会话基本信息。

  • session是区别cookie的另一种记录服务器和客户端会话状态的机制
  • session是基于cookie实现的,session存储在服务器端,sessionid会被存储到客户端的cookie中

服务器为每个用户创建一个会话,存储用户的相关信息,以便多次请求能够定位到同一个上下文,流程如下:

image

这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。

当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。

Web开发中,web-server可以自动为同一个浏览器的访问用户自动创建session,提供数据存储功能。最常见的,会把用户的登录信息、用户信息存储在session中,以保持登录状态。

3.2Session如何判断是否是同一会话

服务器第一次接收到请求时,开辟了一块 Session 空间(创建了Session对象),同时生成一个 sessionId ,并通过响应头的 Set-Cookie:JSESSIONID=XXXXXXX 命令,向客户端发送要求设置 Cookie 的响应;客户端收到响应后,在本机客户端设置了一个 JSESSIONID=XXXXXXX 的 Cookie 信息,该 Cookie 的过期时间为浏览器会话结束。

image

3.3Session的缺点

Session 机制有个缺点,比如 A 服务器存储了 Session,就是做了负载均衡后,假如一段时间内 A 的访问量激增,会转发到 B 进行访问,但是 B 服务器并没有存储 A 的 Session,会导致 Session 的失效。

4.Cookie和Session的区别

  • 作用范围不同,Cookie 保存在客户端(浏览器),Session 保存在服务器端。
  • 存取方式的不同,Cookie 只能保存 ASCII,Session 可以存任意数据类型,一般情况下我们可以在 Session 中保持一些常用变量信息,比如说 UserId 等。
  • 有效期不同,Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效。
  • 隐私策略不同,Cookie 存储在客户端,比较容易遭到不法获取,早期有人将用户的登录名和密码存储在 Cookie 中导致信息被窃取;Session 存储在服务端,安全性相对 Cookie 要好一些。
  • 存储大小不同, 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie。

session用来跟踪会话

  1. session 在服务器端,cookie 在客户端(浏览器)
  2. session 默认被存在在服务器的一个文件里(不是内存)
  3. session 的运行依赖 session id,而 session id 是存在 cookie 中的,也就是说,如果浏览器禁用了 cookie ,同时 session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id)
  4. session 可以放在 文件、数据库、或内存中都可以。
  5. 用户验证这种场合一般会用 session

因此,维持一个会话的核心就是客户端的唯一标识,即 session id

4.1为什么需要 Cookie 和 Session,他们有什么关联?

说起来为什么需要 Cookie ,这就需要从浏览器开始说起,我们都知道浏览器是没有状态的(HTTP 协议无状态),这意味着浏览器并不知道是张三还是李四在和服务端打交道。这个时候就需要有一个机制来告诉服务端,本次操作用户是否登录,是哪个用户在执行的操作,那这套机制的实现就需要 Cookie 和 Session 的配合。

用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建创建对应的 Session ,请求返回时将此 Session 的唯一标识信息 SessionID 返回给浏览器,浏览器接收到服务器返回的 SessionID 信息后,会将此信息存入到 Cookie 中,同时 Cookie 记录此 SessionID 属于哪个域名。

当用户第二次访问服务器的时候,请求会自动判断此域名下是否存在 Cookie 信息,如果存在自动将 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息,如果没有找到说明用户没有登录或者登录失效,如果找到 Session 证明用户已经登录可执行后面操作。

SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。

既然服务端是根据 Cookie 中的信息判断用户是否登录,那么如果浏览器中禁止了 Cookie,如何保障整个机制的正常运转。

第一种方案,每次请求中都携带一个 SessionID 的参数,也可以 Post 的方式提交,也可以在请求的地址后面拼接 xxx?SessionID=123456...

第二种方案,Token 机制。Token 机制多用于 App 客户端和服务器交互的模式,也可以用于 Web 端做用户状态管理。

Token 的意思是令牌,是服务端生成的一串字符串,作为客户端进行请求的一个标识。Token 机制和 Cookie 和 Session 的使用机制比较类似。

当用户第一次登录后,服务器根据提交的用户信息生成一个 Token,响应时将 Token 返回给客户端,以后客户端只需带上这个 Token 前来请求数据即可,无需再次登录验证。

5.什么是Token

5.1为什么要使用Token

因为cookie和session一些自身的缺点,限制了一些功能的实现,比如: cookie:优点是节省服务器空间,缺点不安全。不要保存敏感信息。 session:优点是安全,缺点需要服务器空间(服务器重启,则数据丢失), 是一种最常见的解决方案。而这个时候,我们用token就能更好

5.2Token概述

token的意思是令牌,是服务端生成的一串字符串,作为客户端进行请求的一个标识。 JWT(json web token) 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样。

代码语言:javascript
复制
{
"姓名": "Leo",
"角色": "管理员",
"到期时间": "2023年1月09日0点0分"
}
  • 常见的token组成:UID(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,token+请求数据进行几次md5之后的值)

以后,用户与服务端通信的时候,都要发回这个JSON 对象。服务器完全只靠这个对象认定用户身份。 当然,为了防止用户篡改数据,服务器在生成这个对象的时候,会给他加密一下,就是我们看到的一个长长的字符串。如图所示:

image

使用token:

使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的

1.前端使用用户名跟密码请求首次登录

2.后服务端收到请求,去验证用户名与密码是否正确

3.验证成功后,服务端会根据用户id、用户名、定义好的秘钥、过期时间生成一个 Token,再把这个 Token 发送给前端

4.前端收到 返回的Token ,把它存储起来,比如放在 Cookie 里或者 Local Storage

5.前端每次路由跳转,判断 localStroage 有无 token ,没有则跳转到登录页。有则请求获取用户信息,改变登录状态;

6.前端每次向服务端请求资源的时候需要在请求头里携带服务端签发的Token

7.服务端收到请求,然后去验证前端请求里面带着的 Token。没有或者 token 过期,返回401。如果验证成功,就向前端返回请求的数据。

8.前端得到 401 状态码,重定向到登录页面。

5.3Token和Session的区别

Session是一种记录服务器和客户端会话状态的机制,使服务端有状态化,可以记录会话信息。

token是一种令牌,访问接口(API)时需要的凭证,也像古代进入到城里需要腰牌一样。token使服务器五状态化,不会存储会话信息。

token的安全性要好于session,每次请求都有签名,也就会出现每次的token都会变化,也可以防止一定的攻击。

6.什么是JWT

这里只是简单概述一下关于JWT的相关内容,如果想更深入了解JWT,可以看我这一篇博客。

6.1概述

  • JSON Web Token(简称JWT)是目前最流行的跨越认证解决方案。
  • 是一种认证授权机制
  • JMT是在网络应用环境之间传递声明,而执行的一种基于json的开发标准

6.2JWT的认证流程

image

7.Token和JWT的区别

  • Token需要查库验证token 是否有效,而JWT不用查库,直接在服务端进行校验,因为用户的信息及加密信息,和过期时间,都在JWT里,只要在服务端进行校验就行,并且校验也是JWT自己实现的。 7.1JWT基本原理 JWT是json web token缩写。它将用户信息加密到token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证JWTToken的正确性,只要正确即通过验证。 JWT包含三个部分: Header头部,Payload负载和Signature签名。由三部分生成JwtToken,三部分之间用“.”号做分割。 校验也是JWT内部自己实现的 ,并且可以将你存储时候的信息从JwtToken中取出来无须查库 客户端使用用户名跟密码请求登录 服务端收到请求,去验证用户名与密码 验证成功,服务端会签发一个JwtToken,无须存储到服务器,直接再把这个JwtToken发送给客户端 客户端收到JwtToken以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里 客户端每次向服务端请求资源的时候需要带着服务端签发的JwtToken 服务端收到请求,验证密客户端请求里面带着的 JwtToken, 如果验证成功,就向客户端返回请求的数据

7.2Token基本原理

Token(就是加密的字符串,使用MD5,等不可逆加密算法,一定要保证唯一性)

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

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

验证成功,服务端会签发一个Token保存到(Session,redis,mysql…)中,然后再把这个 Token 发送给客户端

客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里

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

服务端收到请求,验证密客户端请求里面带着的 Token和服务器中保存的Token进行对比效验, 如果验证成功,就向客户端返回请求

9.Json Web Token 和 Session Cookies 的对比

JSON Web Token,简称 JWT,它和 Session都可以为网站提供用户的身份认证,但是它们不一样。

9.1什么是 Json Web Tokens

Json Web Token 的简称就是 JWT,通常可以称为 Json 令牌。它是RFC 7519 中定义的用于安全的将信息作为 Json 对象进行传输的一种形式。JWT 中存储的信息是经过数字签名的,因此可以被信任和理解。可以使用 HMAC 算法或使用 RSA/ECDSA 的公用/专用密钥对 JWT 进行签名。

使用 JWT 主要用来下面两点

  • 认证(Authorization):这是使用 JWT 最常见的一种情况,一旦用户登录,后面每个请求都会包含 JWT,从而允许用户访问该令牌所允许的路由、服务和资源。单点登录是当今广泛使用 JWT 的一项功能,因为它的开销很小。
  • 信息交换(Information Exchange):JWT 是能够安全传输信息的一种方式。通过使用公钥/私钥对 JWT 进行签名认证。此外,由于签名是使用 headpayload计算的,因此你还可以验证内容是否遭到篡改。

9.2Session Cookies

Session Cookies 也称为会话 Cookies,在 Session Cookies 中,用户的登录状态会保存在服务器内存中。当用户登录时,Session 就被服务端安全的创建。

在每次请求时,服务器都会从会话 Cookie 中读取 SessionId,如果服务端的数据和读取的 SessionId 相同,那么服务器就会发送响应给浏览器,允许用户登录。

10.参考文献

  • https://docs.authing.cn/v2/concepts/authentication-vs-authorization.html
  • https://blog.csdn.net/qq_41895003/article/details/130567062
  • https://pdai.tech/md/arch/arch-z-session.html#session-stick
  • https://www.cltphp.com/detail-537.html
  • https://www.coonote.com/note/token-detail.html