首先在这里声明本文章所涉及图片均为靶场环境。
Cookie
是一个通用的客户端存储工具,可以存任何数据,包括用户偏好(像网站语言选择)、广告跟踪 ID,或者其他无关身份验证的数据,就是说也有可能什么ID都不带,只存无关数据(如theme=dark)。
在身份验证场景中,Cookie通常会携带session和token字段:
如果用 session 机制,cookie 通常携带 session ID(一个编号如如 sessionID=abc123),服务器靠这个 ID 去数据库查 session 数据。
如果用 token 机制(如 JWT),cookie 可能直接携带整个 token(包含 ID、权限等信息),或者 token 的某个标识(视实现而定),token 本身包含身份信息,服务器直接验证。
但有些系统不用 cookie 去传递 session ID 或 token,而是用 HTTP 头部(比如 Authorization: Bearer)。
可以理解为在cookie本身并不能作为登录凭证,它只是像个快递包裹一样在客户端和服务端之间传东西,真实的登陆凭证是session ID或者JWT 。
Session
在Web 应用的身份验证过程中,cookie 和 session 机制协同工作以管理用户登录状态,其核心流程如下:
用户登录:当用户成功登录时,服务器生成一个唯一的 session ID(会话标识),并将与该 session ID 关联的 会话数据(如用户 ID、登录状态、权限等)存储在服务器端的会话数据库中。同时,服务器通过 HTTP 响应头的 Set-Cookie 字段将该 session ID 发送到客户端浏览器。
Cookie 存储:浏览器接收到 session ID 后,将其存储在 cookie 中。每次发起 HTTP 请求时,浏览器会自动将包含 session ID 的 cookie 附加到请求头中,发送至服务器。
服务器验证:服务器接收到请求中的 cookie 后,提取 session ID,并根据该 ID 查询会话数据库中对应的会话数据。如果 session ID 有效且匹配到会话数据,服务器确认用户身份,允许访问受保护的资源;否则,拒绝访问。
在这个过程中Cookie 负责在客户端存储和传递 session ID,而服务器端存储与 session ID 关联的会话数据。两者协同工作,完成用户身份验证和会话管理。
Token
Token 是一种用于 Web 应用身份验证的字符串,充当用户身份的“凭证”。简单来说:
定义:Token 是一串由服务器生成的标识,通常是随机字符串(如 abc123xyz),用于验证用户身份。
工作方式:
生成:用户登录时,服务器生成 token,并将其与用户信息(如用户 ID、权限)关联,存储在服务器的数据库或内存中。
传递:Token 通常存放在客户端的 cookie 或通过 HTTP 头部(如 Authorization: Bearer <token>)发送给服务器。
验证:服务器收到 token 后,查询数据库确认其有效性,验证用户身份。
简单而言,普通 Token 就是随机字符串,靠服务器数据库验证,没有内置签名功能。如果加签名,就得自己实现,实际不如直接用 JWT。
JWT
JWT(JSON Web Token)是 token 的一种特殊类型。简单来说:
Token:广义上指用于身份验证的字符串,可以是任何格式(如普通 token 是一串随机字符串,靠服务器数据库验证)。
JWT:是一种特定的 token 标准,结构为 Header.Payload.Signature,自包含用户信息(如用户 ID、权限)和签名,服务器通过验证签名确认其有效性,无需查数据库。
与普通token的区别:普通 token 靠服务器数据库验证,JWT 是自包含的(包含用户信息和签名,无需服务器存储)。
在 Web 应用的身份验证过程中,JWT可以被存入到Cookie里,通过 HTTP 请求传给服务器,这是 JWT 的常见用法,常被用于管理用户登录状态。两者协同工作,通过在客户端和服务器之间传递认证信息来实现安全高效的身份验证。以下是其核心流程:
用户登录:当用户成功登录时,服务器生成一个 token( JWT),该 token 包含用户身份信息(如用户 ID)、权限(如角色)以及有效期等声明。服务器通过 HTTP 响应头的 Set-Cookie 字段将 token 发送到客户端浏览器,或者通过其他方式(如响应体)传递。
Cookie 存储:浏览器接收到 token 后,通常将其存储在 cookie 中(也可存储在 localStorage 或通过 HTTP 头部传递)。每次发起 HTTP 请求时,浏览器会自动将包含 token 的 cookie 附加到请求头中,发送至服务器。
服务器验证:服务器接收到请求中的 cookie 后,提取 token,并验证其有效性(通常通过检查 token 的签名)。如果 token 未被篡改、未过期且签名有效,服务器直接从 token 中解析用户信息,确认用户身份并允许访问受保护的资源;否则,拒绝访问。
Cookie 作为客户端传递 token 的工具,负责在浏览器和服务器之间传输认证信息;token 则是一个自包含的凭证,携带用户身份和权限信息,服务器通过验证 token 完成身份认证。两者协同工作,实现了无状态、高效的登录管理。
JWT组成
JWT分为三部分:Header、Payload、Signature(签名)
流程就是,你登录成功后,服务器生成一张包含 Header(防伪方法)、Payload(你的信息)、Signature(防伪印章)的 JWT,发给你。 你之后访问其他接口时,只要带上这张 JWT,服务器就会:
用自己的密钥和 Header 里的算法,重新计算签名。
对比计算出的签名和 JWT 里的签名是否一致。
一致 → 说明信息没被篡改,且确实是自己发的,就认可你的身份。
不一致 → 认定是伪造的,拒绝访问。
JWT签名工作机制解析
签名是 JWT 的“防伪标签”,通过密钥生成和验证,确保 token 的真实性和安全性。Cookie 负责传递 token,而 token 依靠签名实现无状态的身份验证。
签名生成:
服务器生成 JWT,包含 Header(元信息,如算法)、Payload(用户信息,如用户 ID、角色)和 Signature(签名)。
Header(头部):相当于门票上的 "防伪说明"。
声明 用了XX 防伪技术(比如 HMAC SHA256),类型是 JWT"。
是在告诉服务器 "该用什么方法验证这个“电子通行证”是不是真的"。
Payload(载荷):相当于门票上的 "个人信息",里面存着实际需要传递的数据。
比如 "你的用户 ID 是 123,权限是普通用户,这张票 2 小时后过期"。
注意:这部分信息是公开的(可以被解码查看),就像门票上的信息谁都能看见,所以不能存密码之类的敏感内容。
Signature(签名):相当于通行证上的 "防伪印章"
服务器会用 Header 里指定的算法,把 Header、Payload 和一个只有服务器知道的 "密钥"(比如一个特殊密码)混合在一起,生成一个独一无二的签名,附在门票上。
作用:防止别人篡改信息。比如有人想把 "普通用户" 改成 "管理员",虽然能改 Payload 里的内容,但签名会因为内容变化而失效 —— 服务器验证时发现签名对不上,就会认定这张票是假的,拒绝放行。
签名通过密钥(secret key)和指定算法(如 HMAC-SHA256)对 Base64(Header).Base64(Payload) 进行哈希计算生成。
完整的 JWT(Base64(Header).Base64(Payload).Base64(Signature))通过 HTTP 响应头的 Set-Cookie 字段发送到客户端,存储在 cookie 中。
因此我们的密钥保密是很重要的,密钥泄露可能导致攻击者伪造 token。
密钥大概长x7a9pQz2mW8vT3rY9kL4jF6hN2bP8sD0qX5cV1zA
这样
服务器拿这个密钥(x7a9pQz2mW8vT3rY9kL4jF6hN2bP8sD0qX5cV1zA
)和 JWT 的 Header(算法信息,如 "alg":"HS256")和 Payload(用户信息,如 {"userId":"123"})一起,用哈希算法(如 HMAC-SHA256)算出一个签名,然后拿这个签名与JWT里面的签名做对比,如果一致即可通过。
另外我们还要知道的概念是payload在网络安全领域是个多义术语,在 JSON Web Token(JWT)中,Payload 包含用户身份信息(如用户 ID、角色)和声明(如有效期),通过 Base64 编码存储。
JWT网段区分
我们可以使用:
https://jwt.io/
这个网站在线分解JWT的三个网端。
Cookie、Session 和 Token 的优劣对比
总结:
Cookie 是传递工具,灵活但需加强安全配置。
Session 依赖服务器存储,安全但资源消耗大,适合传统 Web 应用。
Token 无状态、高效,适合现代分布式系统,但需妥善管理有效期和密钥。