序言
在实际应用中,有很大一部分的后台接口应该是在用户登录的情况下才能进行操作的,而这种需要用户认证的接口显然不可能每次都去传一遍用户名和密码,另外不同的用户,操作后台系统的权限也会有所不同,为了解决这些问题,相信你对 token 这个词不陌生吧。
JWT
JSON Web Token ( JWT ),现行的一种开放标准,不局限于编程语言。
JWT 由三部分构成:header (头部)、payload(载荷,也叫 claim)、signature(签名)。
header (头部) 主要有两个部分:
- alg :声明使用的加密算法
- typ :token 的类型,当然这里就是 JWT
payload(载荷)定义了七个标准字段:
- iss :token的发行者
- sub :token面向的用户
- aud :受众
- exp :token的过期时间,Unix时间戳
- nbf :not before , 如果当前时间在 nbf 里的时间之前,则Token不被接受
- iat :token的签发时间,Unix时间戳
- jti :当前token的唯一标识
signature(签名):由 header 和 payload 的base64 编码拼接而成,中间以 . 间隔。
最终的 token 由三部分拼接而成:header 的 base64 编码、payload 的base64 编码、signature 加密后的字符串,中间以 . 间隔。
应用过程
1、用户以正常的用户名和密码成功登录
2、服务器生产 token 返回给用户保存起来
3、用户以后的所有操作均带上 token 以表明合法身份
4、服务器接受 token 检验其合法性以进行后续操作
实战
原理上面说过了,下面写点代码自己生成 token :
看图就知道很简单,加密使用 node 的核心模块 crypto 即可,对时间的操作推荐使用第三方库 moment ,加密算法不建议使用 md5 和 sha1 了,因为已经被证明不安全。
关于 token 验证,base64 反编译 header 和 payload 部分,判断其中的字段是否合法,比如 token 面向的唯一用户对不对得上、时间是否过期等等,当然为了以防篡改,还可以自己重新将签名加密一遍进行比对。
JWT 定义的标准只是一种实现形式,诸如 payload 载荷部分中的字段都是可选的,同样的,我们完全可以自己去定义我们的 json 形式,完全不参照标准字段,只要保证加密验证的一致性即可。说到这,用户权限区分的问题怎么解决,很简单,payload 里面自己加一个表明权限的字段,token 验证的时候判断一下就得了。