[计算机网络]Cookie/Session/JWT
JWT
头部(Header)
头部用于描述关于该 JWT 的最基本的信息,例如其类型以及签名所用的算法等,也可以被表示成一个 JSON 对象。例如:
{"typ":"JWT","alg":"HS256"}
在头部指明了签名算法是 HS256 算法。
经过 Base64 编码得到:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9(第一部分)。
载荷(playload)
载荷就是存放有效信息的地方。这些有效信息包含三个部分:
-
标准中注册的声明(建议但不强制使用)
- Copyiss: jwt签发者
- sub: jwt所面向的用户
- aud: 接收jwt的一方
- exp: jwt的过期时间,这个过期时间必须要大于签发时间
- nbf: 定义在什么时间之前,该jwt都是不可用的.
- iat: jwt的签发时间
- jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击
-
公共的声明
Copy公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息,但不建议添加敏感信息,因为该部分在客户端可解密。Copy{"id":"123456","name":"MoonlightL","sex":"male"}
将该 json 字符串进行 Base64 编码得到:eyJpZCI6IjEyMzQ1NiIsIm5hbWUiOiJNb29ubGlnaHRMIiwic2V4IjoibWFsZSJ9(第二部分)。
-
私有的声明
Copy私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64 是对称解密的,意味着该部分信息可以归类为明文信息。
注意:载荷中的这3个声明并不是都要同时设置。
签证(signature)
jwt的第三部分是一个签证信息。
这个部分需要 Base64 加密后的 header
和Base64 加密后的 payload
使用 “.” 连接组成的字符串,然后通过 header 中声明的加密方式进行加盐 secret(注意这里的加盐,只有我自己知道这个盐,所以只有我能加密并成功解密)组合加密,然后就构成了 jwt 的第三部分。
即将 eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEyMzQ1NiIsIm5hbWUiOiJNb29ubGlnaHRMIiwic2V4IjoibWFsZSJ9 进行 HS256 算法加密(header 定义的加密算法)得到:
e5dda3f17226c1c6ca7435cd17f83ec0c74d62bd8e8386e1a178cd970737f09f(第三部分)。
最后,我们将上述的 3 个部分的字符串通过 “.” 进行拼接得到 JWT:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEyMzQ1NiIsIm5hbWUiOiJNb29ubGlnaHRMIiwic2V4IjoibWFsZSJ9.e5dda3f17226c1c6ca7435cd17f83ec0c74d62bd8e8386e1a178cd970737f09f 。
- 前端通过web表单将用户名和密码提交到后端进行认证,一般为http的post请求。
- 后端通过用户名和秘密进行验证通过后,将一些重要的用户信息,如用户id,用户名作为jwt的payload,将其与头部信息分别进行Base64编码,
- 然后形成签名。形成一个jwt的token,其中token的格式为xxx.yyy.zzz(token head.payload.signature)
- 将生成的jwt串返回给前端,前端将其保存在localstorage或者sessionStorage中,退出登录时前端删除保存的jwt即可。
- 后端访问其他api接口都需要携带token,将其放到http的header的authorization中。(解决XSSF和XSRF问题)
- 后端再次验证token的有效性,验证通过进行后面逻辑的判断访问,返回响应的结果,不通过则进行返回提示错误。
为什么JWT可以防止篡改?
第三部分使用签名算法对第一部分和第二部分的内容进行签名,常用的签名算法是 HS256,常见的还有md5,sha 等,签名算法需要使用密钥进行签名,密钥不对外公开,并且签名是不可逆的,如果第三方更改了内容那么服务器验证签名就会失败,要想保证验证签名正确必须保证内容、密钥与签名前一致。
HTTP是一种无状态协议
,即服务器不保留与客户交易时的任何状态。也就是说,上一次的请求对这次的请求没有任何影响,服务端也不会
对客户端上一次的请求进行任何记录
处理。
HTTP协议的无状态性带来的问题:
- 会话管理: 由于HTTP的无状态性,服务器无法自动识别两个请求是否来自同一用户。为了解决这个问题,通常使用会话(session)来跟踪用户的状态。在会话中,服务器会为每个用户分配一个唯一的标识符(通常是一个会话ID),并在用户的请求之间使用这个标识符来维护状态信息。
- 身份验证: 在无状态的环境中,服务器需要在每个请求中重新验证用户的身份。为了减轻这个问题,通常使用令牌(token)或者基于Cookie的身份验证来维持用户的登录状态。
既然HTTP协议是无状态的,不会记录用户信息,那么怎么样才能让HTTP协议记录用户信息呢?换句话说,服务器怎么判断发来HTTP请求的是哪个用户?
于是,两种用于保持HTTP状态的技术就应运而生了,一个是 Cookie,而另一个则是 Session。
JWT和Token的区别
服务端验证客户端发送的token信息要进行数据的查询操作,Jwt验证客户端发来的token就不用,在服务端使用密钥校验就可以了,不用数据库的查询。
Token需要查库验证token 是否有效,而JWT不用查库或者少查库,直接在服务端进行校验,并且不用查库。因为用户的信息及加密信息在第二部分payload和第三部分签证中已经生成,只要在服务端进行校验就行,并且校验也是JWT自己实现的。
Token
TOKEN概念: 令牌, 是访问资源的凭证。
Token的认证流程:
用户输入用户名和密码,发送给服务器。
服务器验证用户名和密码,正确的话就返回一个签名过的token,
浏览器客户端拿到这个token。
客户端自己保存token,后续每次请求中,浏览器会把token作为http header发送给服务器,服务器验证签名是否有效,如果有效那么认证就成功,可以返回客户端需要的数据。特点:这种方式的特点就是客户端的token中自己保留有大量信息,服务器没有存储这些信息。
Cookie
Cookie 是客户端的存储空间,由浏览器来维持。具体来说 cookie 机制采用的是在客户端保持状态
的方案。Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。
Cookie 可以翻译为“小甜品,小饼干” ,Cookie 在网络系统中几乎无处不在,当我们浏览以前访问过的网站时,网页中可能会出现 :你好 XXX,这会让我们感觉很亲切,就好像吃了一个小甜品一样。
Cookie 的实现过程:
Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie,当下次客户端再往该服务器
发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。
也就是 Cookie 是服务器生成的,但是发送给客户端,并且由客户端来保存。每次请求加上 Cookie就行了。服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
cookie 和 token 的区别
Cookie和Token都是用于管理用户会话和身份验证的机制,但它们在使用场景、存储方式、安全性和实现细节上有显著区别。以下是两者的主要区别:
1. 存储位置
-
Cookie:
Cookie是由服务器生成并存储在客户端(通常是浏览器)中的小数据片段。浏览器在发送请求时会自动携带这些Cookie,因此它们通常被用来存储会话信息或用户偏好设置。 -
Token:
Token是一种用于认证的字符串,通常在服务器生成后发送给客户端。Token可以存储在客户端的多种位置,如本地存储(LocalStorage)、会话存储(SessionStorage)或作为客户端手动管理的变量。Token不会自动随请求发送,需要客户端代码(如JavaScript)在每次请求时手动附加到HTTP头中。
2. 安全性
-
Cookie:
Cookie可以标记为HttpOnly
和Secure
。HttpOnly
标记使得JavaScript无法访问Cookie,增加了防止跨站脚本攻击(XSS)的安全性;Secure
标记要求Cookie只能通过HTTPS发送,防止在传输过程中被截获。然而,Cookie仍然容易受到跨站请求伪造(CSRF)攻击的影响。 -
Token:
Token通常通过HTTP头的Authorization
字段(如Bearer Token)发送,避免了Cookie自动附带的风险。因为Token通常不会自动包含在请求中,所以可以更好地防止CSRF攻击。Token还可以设计为短生命周期或一次性使用,从而增加安全性。
3. 使用场景
-
Cookie:
Cookie主要用于传统的基于会话的身份验证方式,即在用户登录后,服务器在客户端存储一个会话ID的Cookie。此后,每次请求时,浏览器会自动发送这个Cookie,以便服务器识别用户的会话。 -
Token:
Token广泛用于现代的基于JWT(JSON Web Token)或OAuth等方式的无状态身份验证。Token认证方式通常在前后端分离的应用中使用。用户登录后,服务器生成一个Token并返回给客户端,客户端在后续请求中将Token包含在HTTP头中,服务器通过验证Token来识别用户。
4. 无状态性
-
Cookie:
传统的基于Cookie的会话管理是有状态的,因为服务器通常需要在内存或数据库中存储会话数据,并根据Cookie中的会话ID检索该数据。 -
Token:
Token通常用于无状态的认证方式。服务器通过解码和验证Token本身来确定用户身份,而不需要存储会话数据。这种无状态性使得Token认证更适合于分布式和微服务架构。
5. 跨域支持
-
Cookie:
Cookie默认是绑定到特定域名的,可以通过设置SameSite
属性限制其跨域使用。然而,在跨域请求中,处理Cookie的机制比较复杂,需要配置CORS(跨域资源共享)和withCredentials
等参数。 -
Token:
Token更加灵活,不受域名限制,可以方便地在不同域之间传递和使用,这在跨域应用中尤为重要。
6. 实现复杂度
-
Cookie:
Cookie的使用相对简单,浏览器和服务器自动处理大部分Cookie的传递和存储工作,但需要注意安全性和管理的细节。 -
Token:
Token的实现需要更多的开发者手动管理,例如在前端代码中处理Token的存储、传递和刷新等逻辑,尽管如此,Token认证在灵活性和扩展性方面更强。
7. 生命周期管理
-
Cookie:
Cookie有明确的生命周期,可以设置为会话结束或特定的到期时间。浏览器在到期时间后自动删除Cookie。 -
Token:
Token的生命周期通常由服务器控制,可以设置为短期有效或提供刷新机制来延长其有效期。Token的生命周期管理通常结合后端逻辑,例如使用Refresh Token来获取新的Token。
总之,Cookie和Token各有优缺点,选择使用哪种机制主要取决于具体的应用需求、架构和安全考虑。
Session
Session,中文经常翻译为会话,其本来的含义是指有始有终的一系列动作/消息,比如打电话是从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个 Session。然而当 Session 一词与网络协议相关联时,它又往往隐含了“面向连接
”或“保持状态
”这样两个含义。
Session 是另一种记录客户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而 Session 保存在服务器上。
客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,这就是 Session。客户端浏览器再次访问时,只需要从该 Session 中查找该客户的状态就可以了。
虽然 Session 保存在服务器,对客户端是透明的,它的正常运行仍然需要客户端浏览器的支持。这是因为 Session 需要使用Cookie 作为识别标志。HTTP协议是无状态的,Session 不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为 JSESSIONID 的 Cookie,它的值为该 Session 的 id(即放在HTTP响应报文头部信息里的Set-Cookie)。Session依据该 Cookie 来识别是否为同一用户。
Cookie 和 Session 的区别
-
Cookie 数据存放在客户的
浏览器
上,Session 数据放在服务器
上; -
Cookie
不是很安全
,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用 Session ; -
Session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能。考虑到减轻服务器性能方面,应当使用COOKIE;
-
单个Cookie 在客户端的限制是
3K
,就是说一个站点在客户端存放的COOKIE不能超过3K;
如果说 Cookie 机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session 相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。
Cookie 和 Session 的方案虽然分别属于客户端和服务端,但是服务端的 Session 的实现对客户端的 Cookie 有依赖关系
的,上面我讲到服务端执行 Session 机制时候会生成 Session 的 id 值,这个 id 值会发送给客户端,客户端每次请求都会把这个 id 值放到 http 请求的头部发送给服务端,而这个 id 值在客户端会保存下来,保存的容器就是 Cookie,因此当我们完全禁掉浏览器的Cookie的时候,服务端的Session也会不能正常使用
。
- 客户端浏览器将 Cookie 功能禁用,或者不支持 Cookie 怎么办?
一般这种情况下,会使用一种叫做 URL 重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如 sid=xxxxx
这样的参数,服务端据此来识别用户。
Cookie 和 Session 应用场景:
-
登录网站,今天输入用户名密码登录了,第二天再打开很多情况下就直接打开了。这个时候用到的一个机制就是cookie。
-
登录网站时使用的cookie是一种在用户浏览器和网站之间传递信息的小型文本文件。这个机制是通过HTTP协议实现的,具体的过程如下:
-
用户登录过程:
- 用户在网站的登录页面输入用户名和密码,并点击登录按钮。
- 服务器接收到用户的登录请求,验证用户提供的用户名和密码是否正确。
- 如果验证通过,服务器生成一个包含用户身份信息的令牌(token)。
- 服务器将令牌发送给用户的浏览器,同时在响应的HTTP头部中添加一个Set-Cookie头,其中包含了这个令牌信息。
-
浏览器保存Cookie:
- 浏览器收到来自服务器的响应,解析其中的Set-Cookie头,将包含令牌信息的cookie存储在用户本地的cookie存储中。
- 这个cookie通常包含了一些关键信息,如用户ID、过期时间、域名等。
-
下次访问网站:
- 用户第二天再次打开网站时,浏览器会自动将之前存储的cookie信息包含在请求头中。
- 服务器收到请求后,检查请求头中的cookie信息,找到对应的用户令牌。
- 如果令牌有效且未过期,服务器认为用户已经登录,直接返回相应的页面,无需重新验证用户名和密码。
-
Cookie过期处理:
- 每个cookie都有一个过期时间,一旦过期,浏览器将不再发送它。
- 服务器可以设置cookie的过期时间,让浏览器在过期后删除相应的cookie。
- 用户下次访问时,由于cookie已经过期,服务器会要求用户重新登录,重新生成新的cookie。
总体而言,cookie机制通过在用户浏览器和服务器之间传递信息,实现了在用户多次访问同一网站时保持登录状态的功能。然而,需要注意的是,cookie可能会涉及到安全性和隐私方面的问题,因此在实际应用中,开发者需要注意采取一些安全策略,如使用HTTPS协议传输、设置Secure和HttpOnly标志等来增加安全性。
-
-
-
session一个场景是购物车,添加了商品之后客户端处可以知道添加了哪些商品,而服务器端如何判别呢,所以也需要存储一些信息就用到了session。
-
在购物车场景中,通常使用
Session
来存储和跟踪用户的购物车信息。Session
是一种服务器端存储用户信息的机制,它可以在用户访问网站的不同页面时保持用户的状态。以下是购物车中使用Session
的一般过程:-
用户添加商品到购物车:
- 当用户在网站上点击添加商品到购物车时,客户端会发送一个包含商品信息的请求到服务器。
- 服务器接收到请求后,会将商品信息存储在用户的
Session
中。
-
Session标识符的使用:
- 每个用户访问网站时,服务器会生成一个唯一的
Session
标识符,通常是一个长字符串。 - 这个标识符会在用户的浏览器中设置一个
Session
cookie,用于标识用户与服务器之间的会话。
- 每个用户访问网站时,服务器会生成一个唯一的
-
购物车信息存储在Session中:
- 在服务器端,购物车的信息(如商品ID、数量等)被存储在与用户
Session
关联的数据结构中。 - 这样,用户的购物车信息就与其
Session
关联起来了。
- 在服务器端,购物车的信息(如商品ID、数量等)被存储在与用户
-
跨页面的购物车数据获取:
- 当用户在网站的其他页面访问时,浏览器会自动携带包含
Session
标识符的Session
cookie。 - 服务器根据这个标识符找到用户的
Session
数据,从中提取购物车信息,并根据需要动态生成页面,显示购物车的内容。
- 当用户在网站的其他页面访问时,浏览器会自动携带包含
-
Session的生命周期:
Session
数据通常有一个生命周期,即一段时间没有用户活动后会过期。- 过期时,购物车信息将被清除,用户需要重新添加商品。
这样,通过使用
Session
,购物车信息能够在用户在网站的不同页面间进行共享,而无需在每个请求中都传递所有的购物车数据。这种机制帮助实现了用户在整个购物过程中的连续性体验。需要注意的是,为了增加安全性,开发者应该采取一些措施,例如使用HTTPS来加密通信,以防止Session
标识符被恶意截获。 -
-
cookie和session示意
-
服务器
1234 5678 9562 7854 : duanchangfeng 8795 6235 7845 9568 : pangyuanling
-
浏览器
1234 5678 9562 7854 | 30min | www.baiud.com
-
-