发表于: 2018-06-10 17:48:32

2 948



day72



今天完成的事情


1.将JWT继承到代码里

JWT原理

 由三部分组成:header(头部)、payload(载荷)和signature(签名)。在JWT中是用英文句号分隔出来三个串。


头部


这个json中的typ属性,用来标识整个token字符串是一个JWT字符串;它的alg属性,用来说明这个JWT签发的时候所使用的签名和摘要算法,


载荷

payload用来承载要传递的数据,它的json结构是对JWT要传递数据的一组声明,这些声明被JWT标准称为claims,它的每一个“属性值对”其实就是一个claim,每一个claim的都代表特定的含义和作用。比如sub代表这个token的所有人,存储的是所有人的ID;name表示这个所有人的名字;admin表示所有人是否管理员的角色。当后面对JWT进行验证的时候,这些claim都能发挥特定的作用。

claim分为保留的和自定义的,一般来说保留的是足够使用的,如果有些特殊的需要,可以自己定义。

自定义的claim跟JWT标准规定的claim区别在于:JWT规定的claim,JWT的接收方在拿到JWT之后,都知道怎么对这些标准的claim进行验证;而private claims不会验证,除非明确告诉接收方要对这些claim进行验证以及规则才行。

对头部和载荷进行base64编码,我们得到了JWT的前两部分,用. 分隔

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
eyJleHAiOjE1Mjg0NTEwNzkyOTMsInBheWxvYWQiOiJ7XCJpZFwiOm51bGwsXCJ1c2VybmFtZVwiOlwi6Lev6aOe6aOeXCIsXCJwYXNzd29yZFwiOm51bGwsXCJjcmVhdGVBdFwiOm51bGwsXCJ1cGRhdGVBdFwiOm51bGx9In0


签名


对上面base64编码后的结果进行算法加密(用头部里声明的算法),得到jwt的第三部分。这个加密有点类似于MD5,就是得到前两部分的散列值。


验证

 
当接收方接收到一个JWT的时候,首先要对这个JWT的完整性进行验证,这个就是签名认证。它验证的方法就是把header做base64url解码,就能知道JWT用的什么算法做的签名,然后用这个算法,再次用同样的逻辑对header和payload做一次签名,并比较这个签名是否与JWT本身包含的第三个部分的串是否完全相同,只要不同,就可以认为这个JWT是一个被篡改过的串,自然就属于验证失败



需要注意的是,在验证一个JWT的时候,签名认证是每个实现库都会自动做的(就是我们用的jar包有这功能),但是payload的认证是由使用者来决定的。因为JWT里面可能不会包含任何一个标准的claim,所以它不会自动去验证这些claim。
以登录认证来说,在签发JWT的时候,完全可以只用sub跟exp两个claim,用sub存储用户的id,用exp存储它本次登录之后的过期时间,然后在验证的时候仅验证exp这个claim,以实现会话的有效期管理。


关于base64


Base64是一种基于64个可打印字符来表示二进制数据的表示方法。


由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。三个字节有24个比特,对应于4个Base64单元(24/6),即3个字节需要用4个可打印字符来表示。JDK 中提供了非常方便的 BASE64Encoder 和 BASE64Decoder,用它们可以非常方便的完成基于 BASE64 的编码和解码。


所以头部和载荷并没有真正加密,Base64只是种编码格式,任何人都可以逆向解开,jwt的功能在于放篡改,一旦篡改前面的两部分将和签名部分对不上,则验证失败。


 代码实现:见github任务7


2.完成了手机绑定功能


明天计划的事情:

完成邮箱绑定功能


遇到的问题:
暂无
收获:

用户登录是核实ip, 一定程度可以规避风险。

 


返回列表 返回列表
评论

    分享到