node.js(express.js)+mysql注册代码优化

(一)未优化前的代码

实现步骤

一、获取客户端提交到服务器的用户信息,对表单中的数据,进行合法性的效验 代码如下:

// 注册新用户的接口
exports.regUser = (req, res) => {
  // 获取客户端提交到服务器的用户信息
  const userinfo = req.body;
  // 对表单中的数据,进行合法性的效验,如果有一项为空
  if (!userinfo.username || !userinfo.password) {
    return res.send({
      status: 1,
      message: "用户名或密码不合法",
    });
  }
  console.log(userinfo);
};

二、检测用户名是否被占用

/utils/db.js文件的代码如下:

const mysql = require("mysql");
const db = mysql.createPool({
  host: "localhost", // 连接地址
  port: "3306", //端口号
  user: "root", //用户名XXXXXXXX
  password: "XXXXXXXX", //密码
  database: "exapp2", //数据库名
});
module.exports = db;
var db = require("../utils/db");
// 注册新用户的接口
exports.regUser = (req, res) => {
  // 获取客户端提交到服务器的用户信息
  const userinfo = req.body;
  // 对表单中的数据,进行合法性的效验,如果有一项为空
  if (!userinfo.username || !userinfo.password) {
    return res.send({
      status: 1,
      message: "用户名或密码不合法",
    });
  }
   // 检验用户名是否被占用
  // 定义sql语句,查询用户名是否被占用
  var sql = `select * from ev_users where username=?`;
  db.query(sql, userinfo.username, (err, data) => {
    // 执行sql语句失败,
    if (err) {
      return res.send({
        status: 1,
        message: err.message,
      });
    }
    // 判断用户名是否被占用,data.length 大于0说明sql语句查到了该用户名,所以已定被占用
    if (data.length > 0) {
      // console.log("用户名被占用吗,请更换其他用户名");
      return res.send({
        status: 1,
        message: "用户名被占用吗,请更换其他用户名",
      });
    }
    //  res.send("ok");
  });
  console.log(userinfo);
};

三、对密码进行加密

项目安装指定版本bcryptjs库

 npm i bcryptjs@2.4.3
var db = require("../utils/db");
// 导入密码加密
const bcrypt = require("bcryptjs");
// 注册新用户的接口
exports.regUser = (req, res) => {
  // 获取客户端提交到服务器的用户信息
  const userinfo = req.body;
  // 对表单中的数据,进行合法性的效验,如果有一项为空
  if (!userinfo.username || !userinfo.password) {
    return res.send({
      status: 1,
      message: "用户名或密码不合法",
    });
  }
   // 检验用户名是否被占用
  // 定义sql语句,查询用户名是否被占用
  var sql = `select * from ev_users where username=?`;
  db.query(sql, userinfo.username, (err, data) => {
    // 执行sql语句失败,
    if (err) {
      return res.send({
        status: 1,
        message: err.message,
      });
    }
    // 判断用户名是否被占用,data.length 大于0说明sql语句查到了该用户名,所以已定被占用
    if (data.length > 0) {
      // console.log("用户名被占用吗,请更换其他用户名");
      return res.send({
        status: 1,
        message: "用户名被占用吗,请更换其他用户名",
      });
    }
    // 用户名可以使用,对密码进行加密
    // bcrypt.hashSync(客户端明文密码,10) // 第二个参数提高密码的安全性
    userinfo.password = bcrypt.hashSync(userinfo.password, 10);
    //console.log("@", userinfo.password);
    //  res.send("ok");
  });
  console.log(userinfo);
};

四、插入新用户(完整代码)

var db = require("../utils/db");
// 导入密码加密
const bcrypt = require("bcryptjs");
// 注册新用户的接口
exports.regUser = (req, res) => {
  // 获取客户端提交到服务器的用户信息
  const userinfo = req.body;
  // 1.对表单中的数据,进行合法性的效验,如果有一项为空
  if (!userinfo.username || !userinfo.password) {
    return res.send({
      status: 1,
      message: "用户名或密码不合法",
    });
  }
   // 2.检验用户名是否被占用
  // 定义sql语句,查询用户名是否被占用
  var sql = `select * from ev_users where username=?`;
  db.query(sql, userinfo.username, (err, data) => {
    // 执行sql语句失败,
    if (err) {
      return res.send({
        status: 1,
        message: err.message,
      });
    }
    // 判断用户名是否被占用,data.length 大于0说明sql语句查到了该用户名,所以已定被占用
    if (data.length > 0) {
      // console.log("用户名被占用吗,请更换其他用户名");
      return res.send({
        status: 1,
        message: "用户名被占用吗,请更换其他用户名",
      });
    }
    // 3.用户名可以使用,对密码进行加密
    // bcrypt.hashSync(客户端明文密码,10) // 第二个参数提高密码的安全性
    userinfo.password = bcrypt.hashSync(userinfo.password, 10);
    // 4.插入新用户
    // 定义插入新用户的sql语句
    let sql1 = "insert into ev_users set ?";
    // 调用db.query()执行sql语句
    db.query(
      sql1,
      { username: userinfo.username, password: userinfo.password,},
      function (err, data) {
        // 判断sql语句是否执行成功
        if (err) {
          return res.send({ status: 1, message: err.message });
        }
        // 判断影响行数是否为1
        if (data.affectedRows !== 1) {
          return res.send({ status: 1, message: "注册用户失败,请稍后再试" });
        }
        //注册成功
        res.send({ status: 0, message: "注册成功!" });
      }
    );
    //  res.send("ok");
  });
  console.log(userinfo);
};

在这里插入图片描述

(二)优化后的代码

1. 在上面的代码的基础上封装res.send()方法为统一的中间件,在app.js文件中

// 一定要在路由之前封装res.cc函数
app.use((req, res, next) => {
  // status 默认值 1,表示失败的情况
  // err的值,可能时一个错误对象,也可能时以个错误的描述字符串
  res.cc = function (err, status = 1) {
    res.send({
      status,
      message: err instanceof Error ? err.message : err,
    });
  };
  next();
});

然后在注册接口中把res.send修改成统一res.cc,代码如下:

var db = require("../utils/db");
// 导入密码加密
const bcrypt = require("bcryptjs");

// res.cc是在app.js封装的中间件
// 注册新用户的接口
exports.regUser = (req, res) => {
  // 获取客户端提交到服务器的用户信息
  const userinfo = req.body;
  // 对表单中的数据,进行合法性的效验,如果有一项为空
    if (!userinfo.username || !userinfo.password) {
      return res.send({
        status: 1,
        message: "用户名或密码不合法",
      });
    }
  // 检验用户名是否被占用
  // 定义sql语句,查询用户名是否被占用
  var sql = `select * from ev_users where username=?`;
  db.query(sql, userinfo.username, (err, data) => {
    // 执行sql语句失败,
    if (err) {
      //   return res.send({
      //     status: 1,
      //     message: err.message,
      //   });
      return res.cc(err);
    }
    // 判断用户名是否被占用,data.length 大于0说明sql语句查到了该用户名,所以已定被占用
    if (data.length > 0) {
      // console.log("用户名被占用吗,请更换其他用户名");
      //   return res.send({
      //     status: 1,
      //     message: "用户名被占用吗,请更换其他用户名",
      //   });
      return res.cc("用户名被占用吗,请更换其他用户名");
    }
    // 用户名可以使用,对密码进行加密
    // console.log("@@", userinfo.password);
    // bcrypt.hashSync(客户端明文密码,10) // 第二个参数提高密码的安全性
    userinfo.password = bcrypt.hashSync(userinfo.password, 10);
    console.log("@", userinfo.password);

    // 定义插入新用户的sql语句
    let sql1 = "insert into ev_users set ?";
    // const sqlNewUser = "insert into ev_users set ?";
    // 调用db.query()执行sql语句
    db.query(
      sql1,
      { username: userinfo.username, password: userinfo.password },
      function (err, data) {
        // 判断sql语句是否执行成功
        if (err) {
          //   return res.send({ status: 1, message: err.message });
          return res.cc(err);
        }
        // 判断影响行数是否为1
        if (data.affectedRows !== 1) {
          //   return res.send({ status: 1, message: "注册用户失败,请稍后再试" });
          return res.cc("注册用户失败,请稍后再试");
        }
        //注册成功
        res.cc("注册成功", 0);
        // res.send({ status: 0, message: "注册成功!" });
      }
    );

    //  res.send("ok");
  });
  console.log(userinfo);
};


2. 优化username,password 表单数据验证
在实际开发中,前后端都需要对表单的数据进行合法性的验证,而且,后端做为数据合法性验证的最后一个关口,在拦截非法数据方面,起到了至关重要的作用。
单纯的便用 if…else… 的形式对数据合法性进行验证,效率低下、出错率高、维护性差。因此,推荐便用第三方数据验证模块,来降低出错率、提高验证的效率与可维护性,让后端程序员把更多的精力放在核心业务逻辑的处理上.

(1).安装 jOi 包,为表单中携带的每个数据项,定义验证规则:
npm install joi
(2).安装 @escook/express-j01 中间件,来实现自动对表单数据进行验证的功能:
npm install @escook/express-joi
(3).新建schema/user.js
// 导入定义验证规则的包
// const joi = require("@hapi/joi");
const joi = require("joi");
/**
 * string()值必须是字符串
 * alphanum()值只能包含a-zA-ZO-9的字符串
 * min(length) 最小长度
 * max(length) 大长度
 * required() 值是必填项,不能为 undefined
 * pattern(正则表达式) 值必须符合正则表达式的规则
 */

// 定义用户名和密码的验证规则
const username = joi.string().alphanum().min(1).max(10).required();
const password = joi
  .string()
  .pattern(/^[\S]{6,12}$/)
  .required();
// 定义验证注册和登录表单数据的规则对象
exports.reg_login_schema = {
  body: {
    username,
    password,
  },
};
(4).在routes/use.js中引入schema/user.js中的方法reg_login_schema,代码如下:
var express = require("express");
var router = express.Router();
// 引入封装的获取验证码的方法
var unr_handler = require("../controllers/user");

// 1.导入验证数据的中间件
const expressJoi =require('@escook/express-joi')
//  2.导入需要的验证规则对象
const { reg_login_schema } = require('../schema/user')

// 新用户注册
router.post("/regUser",expressJoi(reg_login_schema), unr_handler.regUser);
// router.post("/regUser", unr_handler.regUser);
// 登录
// router.post("/login", unr_handler.login);
module.exports = router;
(5)在 app.js 的全局错误级别中间件中,捕获验证失败的错误,并把验证失败的结果响应给客户端:
const joi = require('joi')
// 定义表单验证失败的错误的中间件,并把验证失败的结果响应给客户端
// 错误中间件
app.use(function (err, req, res, next) {
  // 数据验证失败,instanceof判断
  if (err instanceof joi.ValidationError) {
    return res.cc(err);
  }
  // 未知错误
  res.cc(err)
});
(6)最终优化后注册接口代码如下:
var db = require("../utils/db");
// 导入密码加密
const bcrypt = require("bcryptjs");

// res.cc是在app.js封装的中间件
// 注册新用户的接口
exports.regUser = (req, res) => {
  // 获取客户端提交到服务器的用户信息
  const userinfo = req.body;
  // 对表单中的数据,进行合法性的效验,如果有一项为空
    // if (!userinfo.username || !userinfo.password) {
    //   return res.send({
    //     status: 1,
    //     message: "用户名或密码不合法",
    //   });
    // }
  // 检验用户名是否被占用
  // 定义sql语句,查询用户名是否被占用
  var sql = `select * from ev_users where username=?`;
  db.query(sql, userinfo.username, (err, data) => {
    // 执行sql语句失败,
    if (err) {
      //   return res.send({
      //     status: 1,
      //     message: err.message,
      //   });
      return res.cc(err);
    }
    // 判断用户名是否被占用,data.length 大于0说明sql语句查到了该用户名,所以已定被占用
    if (data.length > 0) {
      // console.log("用户名被占用吗,请更换其他用户名");
      //   return res.send({
      //     status: 1,
      //     message: "用户名被占用吗,请更换其他用户名",
      //   });
      return res.cc("用户名被占用吗,请更换其他用户名");
    }
    // 用户名可以使用,对密码进行加密
    // console.log("@@", userinfo.password);
    // bcrypt.hashSync(客户端明文密码,10) // 第二个参数提高密码的安全性
    userinfo.password = bcrypt.hashSync(userinfo.password, 10);
    console.log("@", userinfo.password);

    // 定义插入新用户的sql语句
    let sql1 = "insert into ev_users set ?";
    // const sqlNewUser = "insert into ev_users set ?";
    // 调用db.query()执行sql语句
    db.query(
      sql1,
      { username: userinfo.username, password: userinfo.password },
      function (err, data) {
        // 判断sql语句是否执行成功
        if (err) {
          //   return res.send({ status: 1, message: err.message });
          return res.cc(err);
        }
        // 判断影响行数是否为1
        if (data.affectedRows !== 1) {
          //   return res.send({ status: 1, message: "注册用户失败,请稍后再试" });
          return res.cc("注册用户失败,请稍后再试");
        }
        //注册成功
        res.cc("注册成功", 0);
        // res.send({ status: 0, message: "注册成功!" });
      }
    );

    //  res.send("ok");
  });
  console.log(userinfo);
};

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
这里提供一个使用 Node.js + Express + MySQL 实现博客系统的示例代码。需要注意的是,这只是一个简单的示例,实际应用中需要根据具体需求进行修改和完善。 app.js: ```javascript const express = require('express'); const bodyParser = require('body-parser'); const mysql = require('mysql'); const app = express(); const port = 3000; app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); // 创建数据库连接 const connection = mysql.createConnection({ host: 'localhost', user: 'root', password: 'password', database: 'blog' }); // 连接数据库 connection.connect((err) => { if (err) { console.error('error connecting: ' + err.stack); return; } console.log('connected as id ' + connection.threadId); }); // 引入路由 const blogRouter = require('./routes/blog'); app.use('/api/blog', blogRouter(connection)); app.listen(port, () => { console.log(`App listening at http://localhost:${port}`) }); ``` routes/blog.js: ```javascript const express = require('express'); const router = express.Router(); module.exports = (connection) => { // 获取所有博客列表 router.get('/', (req, res) => { const sql = 'SELECT * FROM blog'; connection.query(sql, (err, results) => { if (err) throw err; res.send(results); }); }); // 获取指定博客 router.get('/:id', (req, res) => { const id = req.params.id; const sql = `SELECT * FROM blog WHERE id = ${id}`; connection.query(sql, (err, results) => { if (err) throw err; res.send(results[0]); }); }); // 新增博客 router.post('/', (req, res) => { const { title, content } = req.body; const sql = `INSERT INTO blog (title, content) VALUES ("${title}", "${content}")`; connection.query(sql, (err, results) => { if (err) throw err; res.send(`新增博客:${title}, ${content}`); }); }); // 修改指定博客 router.put('/:id', (req, res) => { const id = req.params.id; const { title, content } = req.body; const sql = `UPDATE blog SET title="${title}", content="${content}" WHERE id=${id}`; connection.query(sql, (err, results) => { if (err) throw err; res.send(`修改博客${id}:${title}, ${content}`); }); }); // 删除指定博客 router.delete('/:id', (req, res) => { const id = req.params.id; const sql = `DELETE FROM blog WHERE id=${id}`; connection.query(sql, (err, results) => { if (err) throw err; res.send(`删除博客${id}`); }); }); return router; }; ``` 以上代码实现了一个基本的博客系统,使用了 MySQL 数据库存储博客信息。可以根据实际需求进行修改和完善。需要注意的是,这里的示例代码没有进行参数验证和 SQL 注入防御等安全性方面的处理,实际应用中需要加强安全性方面的处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鸥总

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值