Cookie 和 Session
HTTP 协议是一种无状态协议
,即每次服务端接收到客户端的请求时,都是一个全新的请求,服务器并不知道客户端的历史请求记录;Session 和 Cookie 的主要目的就是为了弥补 HTTP 的无状态特性。
Session 是什么
客户端请求服务端,服务端会为这次请求开辟一块内存空间
,这个对象便是 Session 对象,存储结构为 ConcurrentHashMap
。Session 弥补了 HTTP 无状态特性,服务器可以利用 Session 存储客户端在同一个会话期间的一些操作记录。
Session 如何判断是否是同一会话
服务器第一次接收到请求时,开辟了一块 Session 空间(创建了Session对象),同时生成一个 sessionId ,并通过响应头的 Set-Cookie:JSESSIONID=XXXXXXX 命令,向客户端发送要求设置 Cookie 的响应;客户端收到响应后,在本机客户端设置了一个 JSESSIONID=XXXXXXX 的 Cookie 信息,该 Cookie 的过期时间为浏览器会话结束。
接下来客户端每次向同一个网站发送请求时,请求头都会带上该 Cookie 信息(包含 sessionId ), 然后,服务器通过读取请求头中的 Cookie 信息,获取名称为 JSESSIONID 的值,得到此次请求的 sessionId。
Session 的缺点
Session 机制有个缺点,比如 A 服务器存储了 Session,就是做了负载均衡后,假如一段时间内 A 的访问量激增,会转发到 B 进行访问,但是 B 服务器并没有存储 A 的 Session,会导致 Session 的失效。
Cookies 是什么
HTTP 协议中的 Cookie 包括 Web Cookie
和浏览器 Cookie
,它是服务器发送到 Web 浏览器的一小块数据。服务器发送到浏览器的 Cookie,浏览器会进行存储,并与下一个请求一起发送到服务器。通常,它用于判断两个请求是否来自于同一个浏览器,例如用户保持登录状态。
HTTP Cookie 机制是 HTTP 协议无状态的一种补充和改良
Cookie 主要用于下面三个目的
-
会话管理
-
个性化
-
追踪
创建 Cookie
Set-Cookie
标头,Cookie 通常由浏览器存储,然后将 Cookie 与 HTTP 标头一同向服务器发出请求。
Set-Cookie 和 Cookie 标头
Set-Cookie
HTTP 响应标头将 cookie 从服务器发送到用户代理。下面是一个发送 Cookie 的例子
有效期
,则将其视为持久性 Cookie。在到期指定的日期,Cookie 将从磁盘中删除。
Cookie的 Secure 和 HttpOnly 标记
,下面依次来介绍一下
会话 Cookies
Expires
或
Max-Age
指令。
永久性 Cookies
特定日期(Expires)
或
特定时间长度(Max-Age)
外过期。例如
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
Cookie的 Secure 和 HttpOnly 标记
-
会话 Cookie 中缺少 HttpOnly 属性会导致攻击者可以通过程序(JS脚本、Applet等)获取到用户的 Cookie 信息,造成用户 Cookie 信息泄露,增加攻击者的跨站脚本攻击威胁。
-
HttpOnly 是微软对 Cookie 做的扩展,该值指定 Cookie 是否可通过客户端脚本访问。
-
如果在 Cookie 中没有设置 HttpOnly 属性为 true,可能导致 Cookie 被窃取。窃取的 Cookie 可以包含标识站点用户的敏感信息,如 ASP.NET 会话 ID 或 Forms 身份验证票证,攻击者可以重播窃取的 Cookie,以便伪装成用户或获取敏感信息,进行跨站脚本攻击等。
Cookie 的作用域
Domain
和
Path
标识定义了 Cookie 的作用域:即 Cookie 应该发送给哪些 URL。
Domain
标识指定了哪些主机可以接受 Cookie。如果不指定,默认为当前主机(不包含子域名)。如果指定了
Domain
,则一般包含子域名。
Domain=mozilla.org
,则 Cookie 也包含在子域名中(如
developer.mozilla.org
)。
Path=/docs
,则以下地址都会匹配:
-
/docs
-
/docs/Web/
-
/docs/Web/HTTP
JSON Web Token 和 Session Cookies 的对比
JSON Web Token ,简称 JWT
,它和
Session
都可以为网站提供用户的身份认证,但是它们不是一回事。
JWT 和 Session Cookies 的相同之处
内存中
将不会记住你之前的操作。
什么是 Session Cookies
会话 Cookies
,在 Session Cookies 中,用户的登录状态会保存在
服务器
的
内存
中。当用户登录时,Session 就被服务端安全的创建。
什么是 Json Web Tokens
Json 令牌
。它是
RFC 7519
中定义的用于
安全的
将信息作为
Json 对象
进行传输的一种形式。JWT 中存储的信息是经过
数字签名
的,因此可以被信任和理解。可以使用 HMAC 算法或使用 RSA/ECDSA 的公用/专用密钥对 JWT 进行签名。
-
认证(Authorization)
:这是使用 JWT 最常见的一种情况,一旦用户登录,后面每个请求都会包含 JWT,从而允许用户访问该令牌所允许的路由、服务和资源。
单点登录
是当今广泛使用 JWT 的一项功能,因为它的开销很小。
-
信息交换(Information Exchange)
:JWT 是能够安全传输信息的一种方式。通过使用公钥/私钥对 JWT 进行签名认证。此外,由于签名是使用
head
和
payload
计算的,因此你还可以验证内容是否遭到篡改。
JWT 的格式
.
进行分割,各个部分分别是
-
Header
-
Payload
-
Signature
令牌的类型(即 JWT)
和使用的
签名算法
,例如 HMAC SHA256 或 RSA。
{
"alg": "HS256",
"typ": "JWT"
}
Base64Url
编码形成 JWT 的第一部分。
Payload
,Payload 中包含一个声明。声明是有关实体(通常是用户)和其他数据的声明。共有三种类型的声明:registered, public 和 private 声明。
-
registered 声明
:包含一组建议使用的预定义声明,主要包括
-
public 声明
:公共的声明,可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息,但不建议添加敏感信息,因为该部分在客户端可解密。
-
private 声明
:自定义声明,旨在在同意使用它们的各方之间共享信息,既不是注册声明也不是公共声明。
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
Base64Url
编码形成 JWT 的第二部分。
-
header (base64后的)
-
payload (base64后的)
-
secret
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
拼凑在一起
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
JWT 和 Session Cookies 的不同
密码签名
JSON 是无状态的
无状态
的,因为声明被存储在
客户端
,而不是服务端内存中。
本地
进行,而不是在请求必须通过服务器数据库或类似位置中进行。这意味着可以对用户进行多次身份验证,而无需与站点或应用程序的数据库进行通信,也无需在此过程中消耗大量资源。
可扩展性
可扩展性
。
JWT 支持跨域认证
单个节点的域
或者它的
子域
中有效。如果它们尝试通过第三个节点访问,就会被禁止。如果你希望自己的网站和其他站点建立安全连接时,这是一个问题。
多个节点
进行用户认证,也就是我们常说的
跨域认证
。
JWT 和 Session Cookies 的选型
后记
-
如果禁用了 Cookies,服务器仍会将 sessionId 以 cookie 的方式发送给浏览器,但是,浏览器不再保存这个cookie (即sessionId) 了。
-
如果想要继续使用 session,需要采用
URL 重写
的方式来实现,可以参考 https://www.cnblogs.com/Renyi-Fan/p/11012086.html
。同时标星(置顶)本公众号可以第一时间接受到博文推送。
本文分享自微信公众号 - Java后端(web_resource)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。