文章目录
Cookie:浏览器存储的身份凭证
定义及原理
Cookie是服务端发送给浏览器并储存在本地的一小段文本数据(通常<=4KB),浏览器后续请求自动携带该数据回传服务端
核心作用:
- 会话跟踪:记录用户行为,如购物车商品
- 身份认证:存储用户登录后的身份标识,如session_id
工作流程
- 用户账号密码登录
- 服务端验证账号密码,通过set-Cookie设置session_id
- 浏览器将cookie存储在本地,后续请求自动携带session_id
- 服务端验证session_id
关键特性
存储位置:浏览器本地
生命周期:
- 会话Cookie:浏览器进程关闭时失效 // 没设置Expires和Max_Age
- 持久Cookie:设置Expires和Max_Age,记住登录状态
安全性:
- httpOnly:禁止JS修改,防止xss攻击
- Secure:仅允许https传输 【知识点:https和http的区别】
- SameSite:跨域限制,防止csrf攻击
- strict 只允许相同域名下携带
- loose 允许第三方那个get请求携带
- none 允许第三方携带,但必须配合secure使用
- domain、path:控制作用域
- 判断user_agent来源 // 可被村改
只使用cookie,没有session可以吗?
不安全。cookie可以被篡改,且容量小
优缺点
优点:浏览器原生支持,适合服务端会话管理
缺点:容量小,有跨域限制、易受到csrf攻击(需要配合csrf token验证)等
Session:服务端存储的用户会话
定义和原理
Session是服务器为每个用户分配的唯一会话标识,存储用户登录状态或临时数据
与cookie的关系:
- 服务端通过Cookie将session_id返回客户端
- 客户端后续请求携带该id,服务端通过该id从内存或数据库中查找对应的会话数据
为什么需要Session: http无状态,无法管理用户会话信息
工作流程
- 用户账号密码登录
- 服务端验证账号密码,生成session_id
- 会话跟踪:浏览器请求携带session_id,服务端验证session_id,查询用户信息
- 会话销毁:用户登出或超时时,服务端将删除session_id存储的临时数据
优缺点
优点:服务端控制会话生命周期,安全性高;支持复杂用户数据
缺点:不利于扩展;分布式环境下,扩展需要同步Session信息(如redis集群)
Token:无状态的身份令牌
定义及原理
Token是服务端生成的加密字符串,包含用户身份信息和权限声明;客户端每次请求携带Token,服务端验证其合法性
常见类型:JWT Token 由header、payload、signature三部分组成
工作流程
- 用户账号密码登录
- 服务端生成JWT token
- 浏览器存储token,后续请求在header 中携带,如
Authorization: Bearer <token>
- 服务端验证signature合法性和过期时间,可在token中提取出用户信息
关键特性
- 无状态:服务端不存储token,只需验证签名合法性,利于分布式扩展
- 自包含:token中包含用户信息,减少数据库查询
- 安全性
- signature加密算法保证token不被篡改
- 过期时间
- 敏感信息(如:密码)不存储在token中
优缺点
优点:
- 无状态,利于分布式扩展
- 适合移动端和API服务(如 restful api)
- 能够对权限进行细粒度控制
缺点:
- Token体积大(尤其是包含大的payload时),网络开销大
- 撤销token需要额外机制 // 如:维护黑名单或缩短过期时间
- token过期后需要重新登录,无法像ssion一样自动续期 // 搭配refresh token
Cookie、Session和Token对比
维度 | Cookie | Session | Token |
---|---|---|---|
存储位置 | 浏览器本地 | 服务端存储(内存/redis/数据库) | 客户端 |
状态管理 | 依赖浏览器自动携带 | 服务端维护会话状态 | 无状态,服务端无需存储 |
安全性 | 需配置httpOnly、Secure、SameSite等 | 服务端控制,安全性高 | 依赖加密算法,需防止xss攻击、重放攻击 |
扩展性 | 需要解决跨域问题 | 分布式环境下,需要同步Session数据 | 天然支持分布式 |
适用场景 | 浏览器端会话跟踪,如购物车 | 传统Web应用 | API服务、移动端、微服务架构 |
Cookie、Session和JWT Token的攻击面和防御措施对比
攻击类型 | cookie、Session攻击面 | cookie、Session防御措施 | JWT Token攻击面 | JWT Token防御措施 |
---|---|---|---|---|
XSS攻击(跨站脚本攻击) | 攻击者通过注入恶意脚本窃取cookie | - 输入输出转义、编码、校验 - 设置httpOnly、Secure、Samesite - CSP限制脚本执行 | 取决于存储位置和传输方式; 若存储在localStorage或使用cookie传输token,容易窃取; 若存储在内存(js变量)和通过Authoriaztion header传输不易窃取; | - 输入输出转义、编码、校验 - CSP限制脚本执行 |
会话劫持 | 攻击者通过xss、网络嗅探、暴力破解窃取cookie | - 使用https传输; - 针对暴力破解:依赖ID生成算法强度 - Session设置过期、定期更新 - IP绑定、UA校验(可篡改) | 攻击者通过网络嗅探、暴力破解等窃取 | - 使用https传输; - 针对暴力破解:依赖密钥安全 - 长短Token - - JTI+黑名单:销毁、泄露token添加至黑名单 - IP绑定、UA校验(可篡改) |
CSRF攻击(跨域请求伪造) | 攻击者利用用户已登录状态,诱导用户访问链接,比如转账 | - 表单提交时添加csrf token; - 设置SameSite限制跨域携带 - 双重校验,如:二维码、二次确认 | 天然防御,Token需要显示在header中添加 | - |
会话固定 | 攻击者诱导用户使用固定的cookie值,接管后续会话。 比如登录时携带攻击者提供session_id,后端直接使用提供session_id,未更新session_id | - 登录时生成新的session - 禁止URL携带session_id | token独立生成,无此风险 | - |
重放攻击 | 对于用户已完成的请求重复发送,比如免密支付 | - 请求添加时间戳+签名 - nonce: 一次性随机数 | 对于用户已完成的请求重复发送,比如免密支付 | - 请求添加时间戳+签名 - JTI+黑名单:比如该请求设置唯一标识(JWT ID)放入黑名单10s(限流) - nonce |
服务端资源耗尽 | 攻击者制造大量Session请求,耗尽服务端内存和连接数 | - 熔断、限流 - 分布式Session:使用Redis集中式存储 | 攻击者制造大量请求,耗尽服务端资源 | - 熔断、限流 - 资源隔离,对token验证服务单独部署 |
xss攻击详细介绍:
- 存储型:攻击者将恶意代码放入数据库中,前端获取资源返回浏览器时执行,比如评论内容中插入脚本
- 反射型:攻击者将恶意代码放在URL参数中,前端页面携带参数跳转时执行
- Dom型:攻击者修改DOM结构,执行恶意代码,比如:item.innerHTML = 恶意代码
防御策略总结
Cookie、Session防御优先级
必做:https+httpOnly+定期更新Session+分布式Session(redis集群)
选做:IP绑定、敏感操作二次校验
JWT Token防御优先级
必做:https+signature加密+双token(refresh token定时更新access token)+JTI防止重放
选做:密钥定期更新+客户端存储 localStorage => httpOnly Cookie(+CORS)