如何为 express-validator 制作函数验证器并将其用作中间件?

How to make a function validator for express-validator and use it as Middleware?

我的 register 路由中有这个验证器:

router.post(
  "/register",
  // username must be an email
  body("username")
    .isLength({ min: 4 })
    .withMessage("username must be at least 4 chars long")
    .isLength({ max: 12 })
    .withMessage(" username must be less than 12 chars long")
    .exists()
    .withMessage("username is required")
    .trim()
    .matches(/^[A-Za-z0-9\_]+$/)
    .withMessage("username must be alphanumeric only")
    .escape(),
  body("email")
    .isEmail()
    .normalizeEmail()
    .withMessage("Invalid Email")
    .exists(),
  body("password")
    .isLength({ min: 5 })
    .withMessage("password must be at least 5 chars long")
    .isLength({ max: 30 })
    .withMessage("password must be at max 30 chars long")
    .matches(/\d/)
    .withMessage("password must contain a number")
    .exists(),
  (req, res) => {
    // Finds the validation errors in this request and wraps them in an object with handy functions
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }
    const username = Utils.Clean_input(req.body.username);
    const email = Utils.Clean_input(req.body.email);
    const password = Utils.Clean_input(req.body.password);
    const salthash = Utils.genPassword(password);
    const salt = salthash.salt;
    const hash = salthash.hash;
    const newuser = new User({
      username: username,
      email: email,
      hash: hash,
      salt: salt,
    });
    try {
      newuser.save((err, data) => {
        if (data) {
          res.status(201).json({
            status: 201,
            sucess: true,
            message: "Register Success, verify your email and login",
          });
        } else {
          res.status(400).json({ err });
        }
      });
    } catch (error) {
      res.status(500).json({ errors: "Server is down try again later" });
    }
  }
);

我可以将这些验证方法放在另一个 .js 文件的自定义函数中并导入它们吗?如果是怎么办?

示例:router.post("/register",validation_fucntion,(res,req){..}),validation_function 处理导入到项目中的另一个 .js 文件的验证

express 中间件也可以在数组中声明以实现可重用性。因此,您可以创建 validation 函数,该函数 returns 一个带有验证器的数组。

例如

app.ts:

import express from 'express';
import { body, validationResult } from 'express-validator';

function UserRegisterValidation() {
  return [
    body('username')
      .isLength({ min: 4 })
      .withMessage('username must be at least 4 chars long')
      .isLength({ max: 12 })
      .withMessage(' username must be less than 12 chars long')
      .exists()
      .withMessage('username is required')
      .trim()
      .matches(/^[A-Za-z0-9\_]+$/)
      .withMessage('username must be alphanumeric only')
      .escape(),
    body('email').isEmail().normalizeEmail().withMessage('Invalid Email').exists(),
    body('password')
      .isLength({ min: 5 })
      .withMessage('password must be at least 5 chars long')
      .isLength({ max: 30 })
      .withMessage('password must be at max 30 chars long')
      .matches(/\d/)
      .withMessage('password must contain a number')
      .exists(),
  ];
}

const app = express();
const port = 3000;

app.use(express.json());
app.post('/register', UserRegisterValidation(), (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
  res.sendStatus(200);
});

app.listen(port, () => console.log('HTTP server started at port 3000'));

测试:

⚡  curl -i -X POST -H "Content-Type: application/json"  -d '{"username": "teresa teng"}' http://localhost:3000/register            
HTTP/1.1 400 Bad Request
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 295
ETag: W/"127-wBnvezB+j1d3j/nM62Y93ii4FtM"
Date: Thu, 09 Dec 2021 02:49:12 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{"errors":[{"msg":"Invalid Email","param":"email","location":"body"},{"msg":"password must be at least 5 chars long","param":"password","location":"body"},{"msg":"password must contain a number","param":"password","location":"body"},{"msg":"Invalid value","param":"password","location":"body"}]}% 
 ⚡  curl -i -X POST -H "Content-Type: application/json"  -d '{"username": "teresa teng", "password": "password123", "email": "test@gmail.com"}' http://localhost:3000/register
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/plain; charset=utf-8
Content-Length: 2
ETag: W/"2-nOO9QiTIwXgNtWtBJezz8kv3SLc"
Date: Thu, 09 Dec 2021 02:45:04 GMT
Connection: keep-alive
Keep-Alive: timeout=5

OK%