盒子
盒子

about-token

关于JWT

前文

公司一直采用JWT作为Authorization认证的方案,是前期同事选择的方案。近期在实际使用过程发现,Base64解码能直接将Token中的信息解出来,让我不禁发出疑问,这样的机制不是不安全吗?为什么会大行其道呢?在去jwt.io一番了解后,终于知道了JWT的结构,跟我之前的想法不一样。

正文

JWT全名JsonWebToken,是一种公开的行业标准RFC 7519,用于双方安全地传递信息(英文原文:JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.)
它主要分为3个部分Header 头部 Payload 负载 Signature 签名,使用.符号进行分割。其中header一般是 { "alg": "HS256", "typ": "JWT"}带了加密的算法和类型的信息,然后使用Base64Url编码为第一部分,然后Payload就是token中存储数据的部分,有一些已被使用的的字段如”iss”,”iat”。然后自己的数据举个例子{"sub": "1234567890","name": "John Doe","admin": true},同样被Base64编码后作为第2部分,然后这一串字符串(Header.Payload)再使用声明的加密方式生成Signature作为第三部分,完整的一个JWT就是这样
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
从上文中的介绍中可以看出,前面2部分其实就只是用Base64进行编码产生的,所以毫无疑问能被解出来,但是因为第三部分是实用rsa加密,一般来说难以破解,所以没有什么伪造Token的可能性,但是因为数据不够安全,所以不能像以前cookie或者session方案中将用户信息这些存进去。而且还有一个缺点因为JWT在服务端没有状态,所以我可以从浏览器控制台拿出一个token直接来请求api。
所以我觉得JWT更适用于一次性的命令认证,颁发一个有效期极短的JWT,即使暴露了危险也很小,由于每次操作都会生成新的JWT,因此也没必要保存JWT,真正实现无状态。

后言

原来我以为Token里带的信息是完全加密的,然后做的鉴权也是根据Payload里的字段做的校验,后来发现base64能解密,我的鉴权代码不是没有用了。经过理解了JWT的完整结构,就算别人能伪造Payload中的所有的数据,但是由于不知道加密方式,导致Signature无法被解出,所以相对而言,鉴权还有有效的= =。