jwt

是什么

  • JSON Web Token,
  • 是一种客户端session;
  • 这个token就是一个加密的、缓存了用户信息的 票据;

结构

结构: header.payload.signature


header = JSON格式的base64编码
{
    type: "JWT",
    alg: "SH256"
}


payload = JSON格式的base64编码
{
    <内置>, <公共>, <私有>
} 

header, payload 是明文
signature = 对`header.payload`的一次加盐摘要, 摘要由 header.alg 指定

流程

服务端: 存salt, 对 jwt 签发, 验证;
客户端: 存jwt, 每次请求都带上 jwt;

server 签发:

// 用户登录后, 生成jwt, 然后发送响应报文
header = '...'
payload = '...'
signature = sha256(header+'.'+payload, salt)
jwt = header + '.' + payload + '.' + signature
response_with(jwt)

server 校验:

jwt = request.headers['Authorization']
(header, payload, signature) = parse(jwt)
sha256(header+'.'+payload, salt) == signature

client 每次请求带上jwt:

  • 在http请求头设置字段: Authorization: 'Bearer <JWT>'
  • Bearer 是固定的标识符

分析

优点

stateless,无状态,不用在服务端维护状态

安全问题

replay攻击

  • 原理:中间者录制请求,然后重发
  • 解决:csrf_token 封装成中间件,但这个破坏了 stateless

局限性

登录相关的需求有:

  1. session 持久化
  2. session 共享
  3. 异地登录
  4. 重复登录
  5. 单点登录
  6. 注销

对于<3, 4, 6>,仅靠 stateless 无法实现

改密码,踢下线的思路:

  • 服务端维护一个过期时间较长的refreshtoken
  • 在下一次token过期时用refreshtoken去刷新
  • 如果改了密码,那么重置这个refreshtoken,间接实现踢下线

payload 的考虑

payload 可以缓存用户信息:nickname, avatar
缓存都会面临过期问题,需要重新签发token

  1. 更新昵称头像就重新签发新token
  2. 客户端发现是新token就替换旧的

ref

http://tools.ietf.org/html/rfc7518#section-3.1
http://blog.leapoahead.com/2015/09/07/user-authentication-with-jwt

posted @ 2018-03-18 11:07  twlk28  阅读(216)  评论(0编辑  收藏  举报