[计算机网络]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。
Cookie
Cookie 是客户端的存储空间,由浏览器来维持。具体来说 cookie 机制采用的是在客户端保持状态的方案。Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。
Cookie 可以翻译为“小甜品,小饼干” ,Cookie 在网络系统中几乎无处不在,当我们浏览以前访问过的网站时,网页中可能会出现 :你好 XXX,这会让我们感觉很亲切,就好像吃了一个小甜品一样。
Cookie 的实现过程:
Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie,当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。
也就是 Cookie 是服务器生成的,但是发送给客户端,并且由客户端来保存。每次请求加上 Cookie就行了。服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
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标识符,通常是一个长字符串。 - 这个标识符会在用户的浏览器中设置一个
Sessioncookie,用于标识用户与服务器之间的会话。
- 每个用户访问网站时,服务器会生成一个唯一的
-
购物车信息存储在Session中:
- 在服务器端,购物车的信息(如商品ID、数量等)被存储在与用户
Session关联的数据结构中。 - 这样,用户的购物车信息就与其
Session关联起来了。
- 在服务器端,购物车的信息(如商品ID、数量等)被存储在与用户
-
跨页面的购物车数据获取:
- 当用户在网站的其他页面访问时,浏览器会自动携带包含
Session标识符的Sessioncookie。 - 服务器根据这个标识符找到用户的
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
-
-
