由于面试了前端,但是我简历上写着我会后端所以被问到了token验证这个问题,但是我自己的项目是没有用到的,他问了我jwt的组成结构什么的。。我当然是一问三不知啦,所以回来之后就自己额外做了一下这个token验证。
组成
jwt主要有三部分组成
- header,主要就是存放了你的token类型和你的加密方式。
- playload,一般有签发人,签发时间,过期时间,编号等,这部分是可以添加自己的一些数据进去。
- signature,要生成这个是需要以上两个字段的,还需要一个密钥,这是只有服务端才知道的一个密钥,生成公式HMACSHA256(
base64UrlEncode(header) + “.” +
base64UrlEncode(payload),
secret)
上两个字段的base64加上密钥,通过’.’来进行连接,然后再通过hash256进行加密。
以上三个字段再通过’.’来连接的这样就生成了一个token。
nodejs生成和验证token
我们只需要安装一个jsonwebtoken就可以了。
1 | npm install jsonwebtoken |
1 | /* |
我们使用jwt.sign方法就可以生成这个token,这个方法主要有三个参数,一个就是基本信息,你从前端拿来需要放进token进行加密的东西,然后就是密钥,最后是一个option,我这边是给了一个过期时间为一天。
验证的话我们只要执行下面这一句就行了。
1 | jwt.verify(token,'mengjiawei',(err,decoded)=>{ |
如果验证失败就会输出invalid,验证成功就会输出你的token明文信息
在express路由中的使用
我们生成还是跟之前的一样的,在用户登录的时候生成token并返回,我这边写了个简单的例子,成功则返回token不成功则返回失败
1 | router.post('/login',function(req,res,next){ |
这边可以用postman来测试一下
测试结果:
可以看到成功的返回了token
接下来是对每个请求都要进行token验证。我们需要使用express-jwt这个中间件,
1 | npm install express-jwt |
然后我们可以新建一个check.js
1 | /* |
这边就是对中间件的配置,只要以对象形式传递一个密钥参数即可,unless就是不对哪个路由生效,我这边设置了登录的时候不需要验证token。
然后在route文件夹下的index.js,配置这个中间件
1 | router.use(jwt) |
只要use就可以了,后一个就是如果验证成功了会执行的,next就是去执行接下来的路由。如果验证失败了,会直接告诉前台出错了,前端需要设置拦截器进行处理
我这边他也设置了一个/users/test路由
1 | router.get('/test',function(req,res,next){ |
就简单的返回一句字符串,主要用来测试的。
然后我们前端只要把token放在headers的Authorization字段中就可以了,这个字段是expressjwt规定的,如果不这样设置会报错,说找不到这个字段,然后字段里面的内容要是Bearer+token这个类型的。
比如
Bearer 1eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IjEyMzQ1NiIsInBhc3N3b3JkIjoibWVuZ2ppYXdlaSIsImlhdCI6MTU5MjQ5NDk1NiwiZXhwIjoxNTkyNTgxMzU2fQ.jBkarDsw71y2oXgG19N3Pad2ou2Oz2UDTwhEp9-cJI0
不然的话也会报错,说你的格式错误了,一定要在token前加入Bearer。
比如我们用postman来对刚才产生的token进行验证一下
我们发现成功接收到了返回的数据。
如果我们在改变token,我在之前的token上在加了一个1,结果如下。
他就会说这个token是非法的。前端只要添加一个拦截器在结果返回前对错误进行处理即可。
这样我们的token实现基本的权限验证基本就已经完成了,后续还是可以根据自己的需求来完善的。