不懂就学,什么是JWT?( 三 )

接着我们写一个接口接收这个jwt,并做验证 。
@RestController@RequestMapping("/jwt")public class TestController {@Resourceprivate JwtUtil jwtUtil;@RequestMapping("/test")public Map<String, Object> test(@RequestParam("jwt") String jwt) {//这个步骤可以使用自定义注解+AOP编程做解析jwt的逻辑,这里为了简便就直接写在controller里Claims claims = jwtUtil.parseJWT(jwt);String name = claims.get("name", String.class);String age = claims.get("age", String.class);HashMap<String, Object> map = new HashMap<>();map.put("name", name);map.put("age", age);map.put("code", "0");map.put("msg", "请求成功");return map;}}

不懂就学,什么是JWT?

文章插图
 
像这样能正常解析成功的话,就表示该用户登录未过期,并且已认证成功,所以可以正常调用服务 。那么有人会问了,这个jwt字符串能不能被伪造呢?
除非你知道secretKey,否则是不能伪造的 。比如客户端随便猜一个secretKey的值,然后伪造一个jwt:
eyJhbGciOiJIUzI1NiIsInppcCI6IkRFRiJ9.eNqqVspLzE1VslJ6OnHFsxnzX67coKSjlJgOFDEzqAUAAAD__w.bHr9p3-t2qR4R50vifRVyaYYImm2viZqiTlDdZHmF5Y然后传进去解析,会报以下错误:
不懂就学,什么是JWT?

文章插图
 
还记得原理吧,是根据前面两部分(Header、Payload)加上secretKey使用Header指定的哈希算法计算出第三部分(Signature),所以可以看出最关键就是secretKey 。secretKey只有服务端自己知道,所以客户端不知道secretKey的值是伪造不了jwt字符串的 。
总结最后讲讲JWT的缺点,任何技术都不是完美的,所以我们得用辩证思维去看待任何一项技术 。
  • 安全性没法保证,所以jwt里不能存储敏感数据 。因为jwt的payload并没有加密,只是用Base64编码而已 。
  • 无法中途废弃 。因为一旦签发了一个jwt,在到期之前始终都是有效的,如果用户信息发生更新了,只能等旧的jwt过期后重新签发新的jwt 。
  • 续签问题 。当签发的jwt保存在客户端,客户端一直在操作页面,按道理应该一直为客户端续长有效时间,否则当jwt有效期到了就会导致用户需要重新登录 。那么怎么为jwt续签呢?最简单粗暴就是每次签发新的jwt,但是由于过于暴力,会影响性能 。如果要优雅一点,又要引入Redis解决,但是这又把无状态的jwt硬生生变成了有状态的,违背了初衷 。
所以印证了那句话,没有最好的技术,只有适合的技术 。感谢大家的阅读,希望看完之后能对你有所收获 。
觉得有用就点个赞吧,你的点赞是我创作的最大动力~
我是一个努力让大家记住的程序员 。我们下期再见!!!
能力有限,如果有什么错误或者不当之处,请大家批评指正,一起学习交流!

【不懂就学,什么是JWT?】


推荐阅读