四、使用Express在服务端设置token验证

Token令牌的流程

  • 服务端在收到用户的登录请求的时候,验证用户名和密码
  • 验证成功之后,服务端会生成一个Token令牌,并把这个Token发送给客户端
  • 客户端收到Token之后,可以把它存储在LocalStorage
  • 客户端在每次使用axios发起请求的时候,可以使用请求拦截器把本地存储的Token放在请求头中发送给服务端
  • 服务端收到请求之后,验证请求头中的Token如果验证成功就返回数据,

使用NodeJS生成token

生成Token需要安装两个依赖包

  1. npm i jsonwebtoken -S
    jsonwebtoken有两个方法
    sign 生成token
    verify 验证token

  2. npm i express-jwt -S
    验证token是否过期,并规定那些路由接口不需要验证

Token的组成

完整的token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJ0b20iLCJ1c2VyX2lkIjoiNDU2IiwiaWF0IjoxNjIzMzczOTQzLCJleHAiOjE2MjM0NjAzNDN9.FDSYIP9j7bWQl9ORuMp9EyqNq8neiKwaJeD_LvlQfpc

可以看到token由用"."分隔的三部分组成

  • heade(头部)

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 是经过base64编码之后的结果

格式:

//默认是哈希256加密
{"alg":"HS256","typ":"JWT"}
  • payload(载荷)
eyJ1c2VyX25hbWUiOiJ0b20iLCJ1c2VyX2lkIjoiNDU2IiwiaWF0IjoxNjIzMzczOTQzLCJleHAiOjE2MjM0NjAzNDN9

也是通过base64编码之后的结果
格式:

{"user_name":"tom","user_id":"456","iat":1623373943,"exp":1623460343}

在你加密的时候设置的字段,注意不要把敏感信息设置进去,这里做测试而已。

  • signature(签名)
FDSYIP9j7bWQl9ORuMp9EyqNq8neiKwaJeD_LvlQfpc

这个不是base64编码,而是经过加密之后的数据,需要密钥才行。

使用token

新建token.js

var jwt = require('jsonwebtoken');
var jwtScrect = 'hello_token';  //签名

//登录接口 生成token的方法
var setToken = function (user_name, user_id) {
    return new Promise((resolve, reject) => {
        //expiresln 设置token过期的时间
        //{ user_name: user_name, user_id: user_id } 传入需要解析的值( 一般为用户名,用户id 等)
        const token = jwt.sign({ user_name: user_name, user_id: user_id }, jwtScrect, { expiresIn: '24h' });
        resolve(token)
    })
}
//各个接口需要验证token的方法
var getToken = function (token) {
    return new Promise((resolve, reject) => {
        if (!token) {
            console.log('token是空的')
            reject({
                error: 'token 是空的'
            })
        }
        else {
            //第二种  改版后的
            var info = jwt.verify(token.split(' ')[1], jwtScrect);
            resolve(info);  //解析返回的值(sign 传入的值)
        }
    })
}

module.exports = {
    setToken,
    getToken
}

在server.js中

//引入插件
var vertoken=require('./utils/token')
var expressJwt=require('express-jwt')



//验证token是否过期并规定那些路由不需要验证
app.use(expressJwt({
  secret:'zgs_first_token',
  algorithms:['HS256']
}).unless({
//用户第一次登录的时候不需要验证token
  path:['/login']  //不需要验证的接口名称
}))


//解析token获取用户信息
app.use(function(req, res, next) {
  var token = req.headers['authorization'];
  if(token == undefined){
      return next();
  }else{
      vertoken.getToken(token).then((data)=> {
          req.data = data;
          return next();
      }).catch((error)=>{
          return next();
      })
  }
});

//token失效返回信息
app.use(function(err,req,res,next){
  if(err.status==401){
      // return res.status(401).send('token失效')
       //可以设置返回json 形式  
       res.json({status:401,message:'token失效'})
  }
})

在用户登录接口中设置token


var vertoken = require('../utils/token')

//验证用户名和密码成功之后调用生成token的方法
        vertoken.setToken(name, email).then(token => {
          console.log(token);
          res.end(JSON.stringify({
            code: 200,
            message: '登录成功',
            token: token
            //前端获取token后存储在localStroage中,
            //**调用接口时 设置axios(ajax)请求头Authorization的格式为`Bearer ` +token
          }))

postman测试
四、使用Express在服务端设置token验证_第1张图片
四、使用Express在服务端设置token验证_第2张图片

你可能感兴趣的:(Express,jwt,nodejs,webservice)