与session不同的另一种认证方式--JWT

本文介绍JWT(JSON Web Token)与传统Session的区别,解析JWT的工作原理及其组成部分。JWT是一种用于双方之间传递安全信息的开放标准,其自包含特性使得状态管理不再依赖于服务端,简化了分布式环境下的认证流程。

前言

之前被公司的大飞哥狠狠的鄙视了一次,那次向他请教一个shiro中的session问题,大飞哥无意间说:”现在外面有的公司都不用session来保持状态了”;当时我就奇怪了,不用session难道都把用户信息都保存在cookie中。大飞哥没有说话,只给我了一个眼神。确认过眼神,眼神中饱含着你还太年轻的意思!之后碰巧又遇到项目中的一个单点登录功能,这个功能没有使用CAS框架,虽然CAS本身功能很强大,但是学习的成本也比较高,要彻底理解CAS的使用还是有一点难度的。所以很多公司的单点登录功能就是基于这篇文章的主角(JWT)来实现的,这里来大家一起学习一下JWT。

JWT简介

JWT(全称是 JSON WEB TOKEN)是一种用于双方之间传递安全信息表述性声明规范。JWT作为一个开放的标准(RFC7519),定义了一种简洁的,自包含的方法用于通信双方之间以Json对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。

  • 简洁(Compact): 可以通过URL,POST参数或者在HTTP header发送,因为数据量小,传输速度也很快
  • 自包含(Self-contained):负载中包含了所有用户所需要的信息,避免了多次查询数据库

JWT和传统session的区别

传统的session认证是在用户登录之后将用户信息保存在服务端的session中,然后生成一个对应的sessionid,再将sessionid返回到客户端存在客户端中,当下次客户端再次访问的时候带上cookie中的sessionid,再根据sessionid在服务端中找到对应的session,这样就可以获取到对应session中存储的用户信息了。这种方式的用户状态还是存在与服务端的。
而JWT是在用户登录之后,将用户信息放在Payload中,经过base64url编码的Header,Payload再经过Header中定义的加密算法进行加密拼凑而成的jwt字符串。将这个保存用户信息的jwt保存再客户端本地的cookie(不推荐)或者localstorge中,下次请求的时候再通过post请求参数或者在请求header中自定义属性来传递这个jwt。然后再调用服务端接口服务之前先用过滤器验证一下jwt,如果验证成功则返回对应的服务资源,如果不成功则要求重新登录。具体流程可以参与官网上的这个流程图。
这里写图片描述

JWT 的组成

其实JWT没有想象中的那么高大上,我们可以把他简单理解成一个包含信息,并且能用于用户验证,在服务之前传递信息的字符串。那么这个字符串具体是由哪些部分组成呢?
JWT可以看成是由”.”分隔的三个字符串拼接而成的一个大字符串。这三个字符串分别指代下面几个模块。

  • 头部(Header)
  • 负载(Payload)
  • 签名(Signature)

整个JWT类似于xxxxx.yyyyy.zzzzz,当然实际中各个部分是经过base64编码的字符串。那么这三个部分分别代表了什么呢?
首先是Header,Header大致结构如下

{
  "alg": "HS256",
  "typ": "JWT"    
} 

typ代表类型是JWT类型,alg代表后面签名的加密算法。
接下来是Payload,他是作为一个载体,去承载一些用户想要传递的一些信息,这些信息通常被保存在claim中,对于claim可以大致分为下面三种Reserved claims,Public claims,Private claims

  • Reserved claims 是JWT预留的一些claim,具体有下面几种
iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

这些预留的claim不是强制必须要使用的,我们可以根据自己的情况来大致使用,这些claim的后期验证不需要用户自己去实现检验或者验证有效性,jwt会自己去验证的。
- Public claims
一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密。
- Private claims
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。这些claim跟JWT预留的claim区别在于:JWT预留的claim,JWT的接收方在拿到JWT之后,JWT知道怎么对这些标准的claim进行验证;而private claims不会验证,除非明确告诉接收方要对这些claim进行验证以及规则才行,所以在日常对接中要彼此双方约定对接规则。
具体的Payload大致样子如下

{
  "sub": "123256",
  "name": "aiqinhai",
  "userid":"123"   
} 

最后是Signature,这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了JWT的第三部分。这就是所谓的签名,那么签名是怎么产生的呢,如果采用Header中定义的HS256加密算法来进行签名,签名方法如下

HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload), secret) 

然后把上面的生成的Header,Payload,Signature用”.”进行分割拼凑之后就是完整的JWT。

总结

这里只是科普式地介绍一下JWT的小知识,JWT和session的区别以及jwt的组成。后面再和大家一起学习一下关于JWT的应用场景,以及JWT的优势所在。这里有个关于JWT的小Demo,有兴趣的同学可以在本地跑跑看看效果。复制过来即可用的JWT小Demo

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱琴孩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值