jsonwebtoken生成与解析token

之前写了一篇介绍token的文章:简单理解Token机制token算法自己设计的,使用了随机算法,导致token无法进行反向解密。所以我当初使用了redis进行存储token,前端调用API时需要携带token进行身份验证,token有效期48小时。但是我们有说过:sessionid是需要空间进行存储的,但是token在服务器是可以不需要存储用户信息的。所以我们能不能做到用户注册登陆成功给用户生成一个token返回给客户端,等前端携带token调用API时我们直接解析token看能否解析出用户数据来决定用户是否有接口权限呢?事实上NodeJS提供的一个npm包:jsonwebtoken就可以实现token的生成与反向解密出用户数据。接下来我们看看jsonwentoken如何进行使用。

首先先全局安装一个express-generator,命令为:

npm install -g express-generator

然后使用express-generator快速搭建一个express项目,命令为:

express express_demo

然后进入项目并且安装express项目所需依赖,命令为:

cd express_demo && npm install

到这里项目搭建成功了,我们可以看看项目结构:

首先在util下创建common.js,该文件主要放置常用公共方法,这里我目前只有两个公共方法:paramAll(用来获取前端传来的参数),encryPassword(对密码拼接字符串进行MD5加密)。

可以看到第一行导入crypto依赖,MD5加密需要使用到这个包,所以我们先装下这个依赖,命令为:

npm install --save-dev crypto

然后在util下创建bootloader.js,主要封装几个全局函数,用来输出测试数据以及给前端返回数据使用。

然后打开config.js,配置jsonwebtoken生成token所需的secretsecret为加密密钥,不能泄露给其他人使用。

接下来步入正轨了,我们一直说使用jsonwebtoken生成token,那当然我们首先安装下jsonwebtoken,命令为:

npm install --save-dev jsonwebtoken

接下来我们来写个接口是线下token的生成,我们接口实现在router下实现。首先打开router/users.js,在文件顶部先导入我们刚才编写的几个文件:

接下来我们实现接口,将用户的基本信息结合我们设置的密钥secret通过jsonwebtoken生成token:

通过我们刚才封装的paramAll()进行过去前端的传参,密码是隐私数据所以通过封装好的encryPassword()进行MD5加密。然后结合secret通过jsonwebtoken.sign(info, secret, options)进行加密生成token。我们来看下接口效果:

可以看到我们成功将用户信息转化为token了,接下来我们来看看如何反向解析出用户数据,解析token使用方法:

jsonwebtoken.verify(token, secret ,callback)

我们实现一个接口实现解析用户token获取用户信息:

这里需要注意的一点:如果token解析失败或者token已经过期,则都会返回err,只有正确解析出用户数据才会返回data。我们可以看下效果:

可以看到我们成功把用户数据解析出来,接下来我们可以看看在真正的API接口中我们如何去使用jsonwebtoken去进行token的解析使用。首先我们提到过了接口安全性一般要使用签名,签名规则还是依旧使用我一直使用的规则:

1.将接口所需参数加上当前时间戳参数time,time取毫秒值组装成json对象。
2.将所有参数以key=value的形式按照ASCII的顺序进行排序得到waitSign。
3.对waitSign进行MD5加密,得到signParam.
4.将signParam转化为纯小写,得到最终的签名sign。

那接下来我们首先先把生成签名的算法封装成公共方法放到common.js中:

API接口免不了数据库操作,我们接下来封装下数据库操作。首先在config.js中配置数据库配置信息:

接下来在项目根目录创建db文件夹,在db下创建mysql.js对数据库的增删改查操作进行封装,先封装连接池初始化以及连接池释放方法:

再封装一个用户插入更新数据,一个用于查询数据:

到这里数据库我们也封装好了,我们开始写API实现用户登陆,登陆成功生成token。我们看看实现的代码:

其实登陆逻辑可以分为三个步骤:

1.将参数按照解密规则加密生成签名sign
2.签名验证成功,数据库验证账号密码是否匹配
3.账号密码匹配生成token与用户信息一起返回给前端

我将数据库操作封装到dao层下的users.js下,我们看下登陆数据库的逻辑代码:

到这里登陆逻辑完成了,我们看下接口的调用效果:

调用成功,会生成一个token结合用户信息一起返回给前端。我们再实现一个接口查询用户个人积分信息。前端调用API需要携带token进行验证个人信息。

本接口一样分成三个步骤:

1.将参数按照解密规则加密生成签名sign
2.签名验证成功,解析token验证解析后的用户账号与用户传参的账号是否一致
3.验证成功进行数据库操作查询用户的积分数据返回给前端

一样我们把数据库操作封装在dao/users.js下,我们可以看下数据库逻辑:

我们看下接口调用效果:

可以看到我们成功解析token获得用户信息,并查询到用户的积分信息。

其实在公司前后端交互基本上我们也是采用签名sign + token + timestamp的验证方式。本篇文章也完成的重现了开发接口的整个流程,为了提高代码可维护性,我们将一些公共方法全部进行了封装,为后续的产品迭代增加了更多的可能性。

本篇文章源码以及上篇加解密算法源码已上传码云,下载链接:

https://gitee.com/mqzuimeng/test_code.git

原文发布于微信公众号 - 程序猿周先森(zhanyue_org)

原文发表时间:2019-06-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券