面试必备-深入理解Java jwt

一、 什么是JSON Web Token?

JSON Web Token(JWT)是一个开放式标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间以JSON对象安全传输信息。这些信息可以通过数字签名进行验证和信任。可以使用加密(使用HMAC算法)或使用RSA的公钥/私钥对对JWT进行签名。

二、 为什么使用JWT?

现在都流程微服务架构,到处都是 分布式,通过session管理用户登录状态成本越来越高,因此慢慢发展成为token的方式做登录身份校验,然后通过token去取redis中的缓存的用户信息,随着之后jwt的出现,校验方式更加简单便捷化,无需通过redis缓存,而是直接根据token取出保存的用户信息,以及对token可用性校验,单点登录更为简单。

三、 JWT的构成

JWT是由三部分构成(用.分隔),将这三段信息文本用链接构成了JWT字符串。就像这样

xxxxx.yyyyy.zzzzz

第一部分:头部(header)

第二部分:载荷(payload,该token里携带的有效信息。比如用户id、名字、年龄等等)

第三部分:签名(signature)

1. header

JWT的头部承载的两部分信息:

{

'typ':'JWT', //声明类型,这里是jwt

'alg':'HS256' //声明加密的算法,通常直接使用HMAC SHA256或RSA

}

Header部分的JSON被Base64Url编码,形成JWT的第一部分。

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

2. plyload

这里放声明内容,可以说就是存放沟通讯息的地方,在定义上有3种声明(Claims):

Registered claims(注册声明):

这些是一组预先定义的声明,它们不是强制性的,但推荐使用,以提供一组有用的,可互操作的声明。 其中一些是:iss(发行者),exp(到期时间),sub(主题),aud(受众)等。

Public claims(公开声明):

这些可以由使用JWT的人员随意定义。 但为避免冲突,应在IANA JSON Web令牌注册表中定义它们,或将其定义为包含防冲突命名空间的URI。

Private claims(私有声明):

这些是为了同意使用它们但是既没有登记,也没有公开声明的各方之间共享信息,而创建的定制声明。

示例(这里存放的即使一个用户的信息,没有到期时间、主题之类的声明):

{

"sub": "1234567890",

"name": "Demo",

"admin": true

}

Playload部分的JSON被Base64Url编码,形成JWT的第二部分。

请注意,对于已签名的令牌,此信息尽管受到篡改保护,但任何人都可以阅读。 除非加密,否则不要将秘密信息放在JWT的有效内容或标题元素中。第二部分不要放置敏感数据如银行卡帐号、身份证号等信息。一般存放用户ID、名字、是否管理员、拥有的权限等信息。

3. Signature

第三部分signature用来验证发送请求者身份,由前两部分加密形成。

要创建签名部分,您必须采用编码标头,编码有效载荷,秘钥,标头中指定的算法并签名。

如果你想使用HMAC SHA256算法,签名将按照以下方式创建:

HMACSHA256(

base64UrlEncode(header) + "." +

base64UrlEncode(payload) + "." +

secret)

此secret存在于你的服务器端,打死都不要告诉任何人,否则就泄密了。

JWTs作为OAuth2.0关于Access_Token的具体解决方案, 为RFC 7519提出,但是后面又有个RFC 6750定义了Bearer Token,就是设置请求头:

Authorization: Bearer <token>。/<token>

四、 JWT 的使用方式

1. 客户端用户发登录请求。

2. 服务端验证用户名密码。

3. 验证成功服务端生成一个token,响应给客户端。

4. 客户端之后的每次请求header中都带上这个token,一般放在HTTP 请求的头信息Authorization字段里面。

5. 服务端对需要认证的接口要验证token,验证成功接收请求。

五、 JWT的优点

体积小,因而传输速度更快多样化的传输方式,可以通过URL传输、POST传输、请求头Header传输(常用)简单方便,服务端拿到jwt后无需再次查询数据库校验token可用性,也无需进行redis缓存校验在分布式系统中,很好地解决了单点登录问题很方便的解决了跨域授权问题,因为跨域无法共享cookie。

六、 JWT的缺点

因为JWT是无状态的,因此服务端无法控制已经生成的Token失效,是不可控的,这一点对于是否使用jwt是需要重点考量的获取到jwt也就拥有了登录权限,因此jwt是不可泄露的,网站最好使用https,防止中间攻击偷取jwt在退出登录 / 修改密码时怎样实现JWT Token失效。

面试必备-深入理解Java jwt

七、 Jwt + redis

1. 为什么使用redis

采用jsonwebtoken生成token时可以指定token的有效期,并且jsonwebtoken的verify方法也提供了选项来更新token的有效期,但这里使用了express_jwt中间件,express_jwt不提供方法来刷新token。

2. 使用方式:

1. 客户端请求登录成功,生成token。

2. 将此token保存在redis中,设置redis的有效期(例如1h)。

3. 新的请求过来,先express_jwt验证token,验证成功, 再验证token是否在redis中存在,存在说明有效。

4. 有效期内客户端新的请求过来,提取token,更新此token在redis中的有效期。

5. 客户端退出登录请求,删除redis中此token。


分享到:


相關文章: