http 的 cookie 和 jwt
30 September 2018

cookie 的 httponly

来源:Session Cookie的HttpOnly和secure属性

Cookie 的 HttpOnly 和 secure 属性

  1. secure 属性
    当设置为 true 时,表示创建的 Cookie 会被以安全的形式向服务器传输,也就是只能在 HTTPS 连接中被浏览器传递到服务器端进行会话验证,如果是 HTTP 连接则不会传递该信息,所以不会被窃取到 Cookie 的具体内容。
  2. HttpOnly 属性
    如果在 Cookie 中设置了"HttpOnly"属性,那么通过程序(JS 脚本、Applet 等)将无法读取到 Cookie 信息,这样能有效的防止 XSS 攻击。

存储登录用的信息(敏感信息)的原则:

  1. 不能存 localstorage
  2. 存 cookie 必须设置 httponly 为 true

jwt

来源:讲真,别再使用JWT了 (有点标题党,但值得一读)

介绍

一种基于JSON的、用于在网络上声明某种主张的令牌(token)。JWT通常由三部分组成: 头信息(header), 消息体(payload)和签名(signature)。

头信息指定了该JWT使用的签名算法,消息体包含了JWT的意图(参数),签名则通过私有的key(存服务器端)根据header 的签名算法计算而成。

我们暂时把他理解为 session 的一种(但是需要加密和解密)

jwt 做登录的好处

jwt 自身可以带一些 payload

jwt 做登录的缺陷

  1. 将 session 的机制重新实现了一遍
  2. 需要加密运算
  3. jwt 提前过期的处理方式不优雅(例如用户注销,实际上 jwt 在 server 端还在,只是 client 端的 cookie 删除了 【当然,这个也可以实现。只是 session 自带就有这种机制】)

jwt 做登录最大的缺陷是需要加密计算,如果不考虑这个,没什么大问题

jwt 的使用场景

JWT(其实还有 SAML)最适合的应用场景就是“开票”,或者“签字”。

在有纸化办公时代,多部门、多组织之间的协同工作往往会需要拿着 A 部门领导的 “签字” 或者 “盖章” 去 B 部门 “使用” 或者 “访问” 对应的资源,其实这种 “领导签字/盖章” 就是 JWT,都是一种由具有一定权力的实体 “签发” 并 “授权” 的 “票据”。一般的,这种票据具有可验证性(领导签名/盖章可以被验证,且难于模仿),不可篡改性(涂改过的文件不被接受,除非在涂改处再次签字确认);并且这种票据一般都是“一次性”使用的,在访问到对应的资源后,该票据一般会被资源持有方收回留底,用于后续的审计、追溯等用途。

举两个例子:

  1. 员工李雷需要请假一天,于是填写请假申请单,李雷在获得其主管部门领导签字后,将请假单交给 HR 部门韩梅梅,韩梅梅确认领导签字无误后,将请假单收回,并在公司考勤表中做相应记录。
  2. 员工李雷和韩梅梅因工外出需要使用公司汽车一天,于是填写用车申请单,签字后李雷将申请单交给车队司机老王,乘坐老王驾驶的车辆外出办事,同时老王将用车申请单收回并存档。

在以上的两个例子中,“请假申请单”和“用车申请单”就是 JWT 中的 payload,领导签字就是 base64 后的数字签名,领导是 issuer,“HR 部门的韩梅梅”和“司机老王”即为 JWT 的 audience,audience 需要验证领导签名是否合法,验证合法后根据 payload 中请求的资源给予相应的权限,同时将 JWT 收回。

总结

在 Web 应用中,别再把 JWT 当做 session 使用,绝大多数情况下,传统的 cookie-session 机制工作得更好
JWT 适合一次性的命令认证,颁发一个有效期极短的 JWT,即使暴露了危险也很小,由于每次操作都会生成新的 JWT,因此也没必要保存 JWT,真正实现无状态。