express开发api指南--登录token验证

发布时间 2023-05-25 16:52:17作者: 火炬冬天

先安装依赖

cnpm install --save express-jwt jsonwebtoken

增加登录接口,在routes下新建login.js,内容如下:

var express = require("express");
var router = express.Router();
var jwt = require("jsonwebtoken"); //生成token
var secretkey = "miyao"; // 自定义秘钥
var { db } = require("../database/db");
var { resultInfo } = require("../util");

/* 登录相关. */
/**,
 * @swagger
 * /api/login:
 *    post:
 *      tags:
 *       - login
 *      summary: 登录
 *      requestBody:
 *         description: 参数格式
 *         required: true
 *         content:
 *          application/json:
 *            schema:
 *              $ref: '#/components/info'
 *      responses:
 *        200:
 *          description: 成功返回格式
 *          content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/callback'
 * components:
 *    info:
 *      tyep: object
 *      properties:
 *        username:
 *          type: string
 *          description: 账号
 *          example: ''
 *        password:
 *          type: string
 *          description: 密码
 *          example: ''
 *    callback:
 *      type: object
 *      properties:
 *         Code:
 *          type: integer
 *          format: int64
 *          example: 0
 *         Data:
 *          type: array
 *          example: []
 *         Message:
 *           type: string
 *           example: ''
 *
 */
//登录
router.post("/login", function (req, res, next) {
  var sql = `select * from t_sys_user where user_no = '${req.body.username}' and user_password = '${req.body.password}'`;
  db.result(sql)
    .then((result) => {
      //实际应该有匹配,测试无所谓
      if (result.rowCount >= 0) {
        //第一个参数是token中需要的信息
        //第二个参数是加密用的秘钥,第三个参数为token过期的时间,实际一般设置1天,60*60*24=86400。这边为了测试设置60s
        var tokentstr = jwt.sign({ username: "001" }, secretkey, {
          expiresIn: "60s",
        });
        var obj = {
          username: req.body.username,
          password: req.body.password,
          token: tokentstr,
        };
        res.send(resultInfo(0, obj, "success"));
      }
    })
    .catch((error) => {
      res.send(resultInfo(1, "", error.detail || error.hint));
    });
});
module.exports = router;

修改app.js

// 自定义秘钥
var secretkey = "miyao"; 
// 引入解码工具
var { expressjwt } = require("express-jwt"); 
//引入login.js
var loginRouter = require("./routes/login"); 
//只要配置express-jwt这个中间件,就可以把解析出来的信息挂载在req.auth
//unless里配置不需要验证的地址
app.use(
  expressjwt({ secret: secretkey, algorithms: ["HS256"] }).unless({
    path: [
      "/api/login",
      /^\/swagger\//,
    ],
  })
);
//把login模块注入
app.use("/api", loginRouter, indexRouter, usersRouter);
//修改error handler那里,配置没有登录权限的统一返回
// error handler
app.use(function (err, req, res, next) {
  if (err.name == "UnauthorizedError") {
    res.send(resultInfo(401, "", "token expired"));
  } else {
    res.send(resultInfo(500, "", "server error"));
  }
});

这个时候你发现怎么在swagger体现那个锁的icon标记呢
在之前的index.js里的swagger配置里加上security属性

//在每一个需要token验证的swagger接口里配置
//以上面查询接口为例
/api/msdMsl/search:
 *    get:
 *      tags:
 *       - MSL
 *      summary: 查询所有
 *      responses:
 *        200:
 *          description: 成功返回格式
 *          content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/callback'
 *      security:
 *        - Authorization: []
 //中间parameters省略,就是在最后加上了security: -Authorization: []
 //这个Authorization: []则是定义在了末尾
 //在components下的最后定义了
 *  securitySchemes:
 *      Authorization:
 *        type: apiKey
 *        name: Authorization
 *        in: header

这个时候点击swagger上面的锁标志,就能弹出这个输入token的图片了
这个时候测试之前的增删改查接口,发现就会报错401,token expired。
这个时候先去执行登录接口,因为登录接口里面我没有验证账号密码,所以直接登录就能得到token。
把token复制到弹框里,并且在前面加上Bearer 。
完整的token应该是‘Bearer token’。然后再掉接口,发现就OK了。