laiyuquan

博客

JWT -- 理论介绍、实战、问题QA(1)

理论基础篇

JWT 是什么?

JWT:Json Web Token 是一个非常轻巧的规范,允许我们在用户和服务器传递安全可靠的信息;

· jwt 可以跨多种语言进行工作,.NET, Python, Node.js, Java, PHP, Ruby, Go, JavaScript;

·jwt 是自带信息体;意味着:通过jwt本身就可以携带基本信息,非常利于信息传递;

·jwt 本身是由三个部分组成的字符串,可以很容易传递;

JWT的组成

jwt由三个部分组成:头部 header  、载荷  payload、签名 signature,每部分中间用. 进行分割。

《JWT -- 理论介绍、实战、问题QA(1)》

头部 (header)

头部包含了两个基本信息:

{
    "typ": "JWT",   #定义了Type
    "alg": "HS256",#具体的签名算法
}

然后进行base64encode编码,就是第一部分的内容:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
载荷(Payload)

这部分就是具体承载信息的部分,通常也称JWT Claims.

通常分为三个部分:registered claim, public claim, and private claim. (翻译太奇怪了,就不翻译了)

Registered Claims

主要包换了一些标准的claims:

  • “iss”   :   ‘‘laiyuquan’’                      # jwt的签发者;
  • “sub” : “374522516@qq.com”   #jwt的主要信息,具体所面向的用户
  • “aud” : “www.laiyuquan.com”  #jwt具体面向地址
  • “exp” : “1500819855”                 #jwt过期的时间戳
  • “iat”  : “1490819753”                  #jwt签发的时间

public claim

公共的claim 包含一些 姓名、和一些基本信息;(可以不用)

Private Claims

一般是一些个人的信息;(基本不用)

举个例子:

包含两个registered claims(iss、exp) 和 两个public claims (name 、admin)

{
  "iss": "scotch.io",
  "exp": 1300819380,
  "name": "Chris Sevilleja",
  "admin": true
}

然后进行base64encode编码,就是第二部分的内容:

eyJpc3MiOiJzY290Y2guaW8iLCJleHAiOjEzMDA4MTkzODAsIm5hbWUiOiJDaHJpcyBTZXZpbGxlamEiLCJhZG1pbiI6dHJ1ZX0

签名 (Signature)

将头部 和 载荷 两部分信息,用一个secret 进行签名,就得到了第三个部分:

var encodedString = base64UrlEncode(header) + "." + base64UrlEncode(payload);

HMACSHA256(encodedString, 'secret'); 这样就得到了 第三个组成部分:
03f329983b86f7d9a9f5fef85305880101d5e302afafa20154d094b229f75773

 

最终完整的jwt:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzY290Y2guaW8iLCJleHAiOjEzMDA4MTkzODAsIm5hbWUiOiJDaHJpcyBTZXZpbGxlamEiLCJhZG1pbiI6dHJ1ZX0.03f329983b86f7d9a9f5fef85305880101d5e302afafa20154d094b229f75773

 


QA篇章:

Q :JWT存放在哪里?

A :JWT 是存放在客户端的, 服务端不需要存,服务端通过解析获得用户的信息(这就是jwt最大的特点)

 

Q : 信息通过base64编码,是可逆的,放在payload 的信息不就暴露了?

A : 是的,所以我们不要存放敏感的信息; 一般用户信息 存user_id 能够识别具体的用户就ok了

 

Q : payload 有exp 过期时间戳,jwt也有过期的概念吗?

A :从jwt本身的设计理论其实 jwt 是不会自动过期的,但我们实际运用过程中

如果一个token长期有效,就会产生各种各样的问题(重放攻击),不是一个安全的策略。

所以一般设置 exp 字段,然后用程序处理jwt的过期,让之失效;

 

Q : jWT 一般设置多长有效时间为好?

A :具体分应用场景:

如果是web应用:一般以天为单位(比如设置3天 即3天不登录 就自动重新登录)

当然也有人 设置2个小时; 也有一定的道理,主要还是从安全角度考虑;

如果是APP应用 :以月为单位(比如设置6个月 、或者12个月)

也有人设置永不过期,也可以吧

 这里的有效期设计逻辑:还是要看具体的业务场景 和 对安全的敏感程度

 

Q :改密码 或者 注销时,需要注销吗?

A :改密码:如果是单应用,我觉得改密码 就完全不影响jwt,因为改完密码你不会再进行登录;

如果是多应用,这就要将原先的jwt token 注销掉,产生新的token了;

注销: 注销 退出登录之类的应用,客户端清空jwt token 即可;

当然,服务端将token 同时注销也OK;

从安全角度考虑: 还是同时注销服务端的j’wt token 更为稳妥;

 

Q : jwt 是保存在客户端的, 怎么进行注销呢?

A :这就在程序中 会引入黑名单功能,将注销的token 放入黑名单中;

 

Q:jwt的失效 和 黑名单 本质上都是让token无效, 两者有什么区别吗?

A: 失效:是指有效时间过期了, 这个直接通过程序判断即可

黑名单: 这个设计主要是为了:刷新token ,或者 注销token ,要让原先的token无效,

黑名单是需要进行存储的, 一般放redis 即可!

 

Q:刷新token?jwt 存放在客户端, 还是怎么刷新呢?

A:服务端设计:在过去失效3分钟之前,不会刷新token

如果检测在3分钟之内了,就会进行刷新token

所谓刷新token:就旧的token加入黑名单,产生新的token; 然后接口都会返回jwt token

前端或者客户端判断:如果服务端返回的token 和 本地存储的token不同,

则将本地存储的token 存储为服务端返回的新token;

 

Q:刷新token功能,是否会有并发失效的功能?

A:可能会,这里要新增黑名单的延期失效功能,比如黑名单延期生效3分钟;


 

下一篇文章: 就用laravel框架 采用tymon/jwt 类具体实战演示一遍

 

 

点赞

发表评论