1、初始化
1.1、创建项目
- 创建 express-login-registry-service 文件夹作为项目目录
mikdir express-login-registry-service
- 初始化包管理配置文件
cd express-login-registry-service
npm init -y
- 安装express
npm i express@4.18.1
- 根目录下新建 app.js 文件作为入口,并初始化如下代码:
// 导入 express 模块
const express = require("express");
// 创建 express 服务器实例
const app = express();
// 配置解析表单数据的中间件
app.use(express.urlencoded({ extended: false }));
// 调用 app.listen 方法,指定端口号启动 web 服务器
app.listen(18060, () => {
console.log("api server running at http://127.0.0.1:18060");
});
1.2、配置 cors 跨域
- 运行如下命令,安装 cors 中间件
npm i cors@2.8.5
- 在 app.js 中添加配置
// 导入 cors 中间件,解决跨域问题
const cors = require("cors");
// 将 cors 注册为全局中间件
app.use(cors());
1.3、初始化路由相关
- 新建 router 文件夹,新建 user.js 并初始化代码如下:
// 导入 express 模块
const express = require("express");
// 创建路由对象
const router = express.Router();
// 导入用户路由处理函数模块
const userHandler = require("../routerHandler/user");
// 注册新用户
router.post("/register", (req, res) => {
res.send('register OK');
});
// 登录
router.post("/login", (req, res) => {
res.send('login OK');
});
// 将路由对象共享出去
module.exports = router;
- 新建 routerHandler 文件夹,新建 user.js 并初始化代码如下:
// 注册用户的处理函数
exports.register = (req, res) => {
res.send('register OK');
};
// 登录的处理函数
exports.login = (req, res) => {
res.send('login OK');
};
- 抽离用户路由模块处理函数,修改 router 文件夹下的 user.js 文件
// 导入用户路由处理函数模块
const userHandler = require("../routerHandler/user");
// 注册新用户
router.post("/register", userHandler.register);
// 登录
router.post("/login", userHandler.login);
- 注册路由模块,修改 app.js 文件
// 导入路由模块
const userRouter = require("./router/user");
// 注册路由模块
app.use("/user", userRouter);
2、表单验证
2.1、新增表单数据验证
- 安装表单验证模块
npm i joi@17.6.0
- 根目录下新增 schema 文件夹,新建 user.js 文件并初始化代码:
// 导入定义验证规则的包
const joi = require("joi");
// 定义用户名和密码的验证规则
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,
},
};
- 安装 @escook/express-joi 验证数据表单中间件
npm i @escook/express-joi
- 修改 router 目录下的 user.js 文件,增加验证表单中间件
// 导入验证规则对象
const { reg_login_schema } = require("../schema/user");
// 导入验证数据的中间件
const expressJoi = require("@escook/express-joi");
// 注册新用户
router.post("/register", expressJoi(reg_login_schema), userHandler.register);
// 登录
router.post("/login", expressJoi(reg_login_schema), userHandler.login);
- 定义错误处理中间件,在 app.js 添加如下代码,并写在路由下面
// 定义错误级别中间件
app.use((err, req, res, next) => {
// 验证失败导致的错误
if (err instanceof joi.ValidationError)
return res.send({
status: 400,
msg: "请求参数不合法" + err.message,
});
// 身份认证失败错误
if (err.name === "UnauthorziedError")
return res.send({ status: 401, msg: "无效的token!" });
// 其它错误
res.send({
status: 500,
msg: err.message,
});
});
3、安装配置mysql
- 安装 mysql 模块
npm i mysql@2.18.1
- 根目录下新建 db 文件夹,新建 index.js 文件并写入如下代码:
// 导入 mysql 模块
const mysql = require("mysql");
// 创建数据库连接对象
const db = mysql.createPool({
host: "120.48.122.12",
user: "root",
password: "19940714",
database: "mysql_db",
});
// 向外共享 db 数据库连接对象
module.exports = db;
- 新建 mysql_db 数据库,并新建 users 表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(0) NOT NULL,
`username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of users
-- ----------------------------
SET FOREIGN_KEY_CHECKS = 1;
4、注册接口
- 修改routerHandler 文件夹下的 user.js 文件
// 导入数据库操作模块
const db = require("../db");
- 安装 bcryptjs 对密码进行加密处理
npm i bcryptjs@2.4.3
- 修改routerHandler 文件夹下的 user.js 文件
// 导入 bcryptjs
const bcrypt = require("bcryptjs");
- 注册接口处理函数
// 注册用户的处理函数
exports.register = (req, res) => {
// 获取客户端请求的用户信息
const userInfo = req.body;
// 定义 SQL 语句,查询用户名是否被占用
const sql = "SELECT * FROM users WHERE username = ?";
db.query(sql, userInfo.username, (err, results) => {
// 执行 SQL 语句失败
if (err) return res.send({ status: 500, msg: err.message });
// 判断用户名是否被占用
if (results.length > 0) {
return res.send({ status: 400, msg: "用户名被占用,请更换其他用户名!" });
}
// 调用 bcrypt.hashSync() 对密码进行加密
userInfo.password = bcrypt.hashSync(userInfo.password, 10);
// 定义插入新用户的 SQL 语句
const sql = "INSERT INTO users SET ?";
db.query(sql, userInfo, (err, results) => {
// 执行 SQL 语句失败
if (err) return res.send({ status: 500, msg: err.message });
// 判断影响行数是否为 1
if (results.affectedRows !== 1)
return res.send({ status: 500, msg: "注册用户失败,请联系管理员!" });
res.send({ status: 200, msg: "用户注册成功!" });
});
});
};
5、登录
5.1、登录接口
- 根目录下新建 config 文件夹,新建 index.js 文件并写入如下代码:
module.exports = {
// 加密和解密 Token 的秘钥
secretKey: "alhuang12138",
// token 的有效期
expiresIn: "2h",
};
- 安装 jsonwebtoken token生成包
npm i jsonwebtoken@jsonwebtoken
- 修改 routerHandler 文件夹下的 user.js 头部加入如下代码
// 导入 jwt 生成 token 包
const jwt = require("jsonwebtoken");
// 密钥和token生效时间
const { secretKey, expiresIn } = require("../config");
- 登录用户处理函数
// 登录的处理函数
exports.login = (req, res) => {
// 接收客户端传递的表单数据
const userInfo = req.body;
// 定义 SQL 查询语句
const sql = "SELECT * FROM users WHERE username = ?";
db.query(sql, userInfo.username, (err, results) => {
// 执行 SQL 语句失败
if (err) res.send({ status: 500, msg: err.message });
// 执行 SQL 语句成功,但查询条数不等于1
if (results.length !== 1)
return res.send({ status: 403, msg: "登陆失败,请检查用户名和密码!" });
// 判断密码是否正确
const flag = bcrypt.compareSync(userInfo.password, results[0].password);
if (!flag) return res.send({ status: 403, msg: "登录失败,密码错误!" });
// 对用户信息进行加密,生成Token字符串
const token = jwt.sign({ username: req.body.username }, secretKey, {
expiresIn: expiresIn,
});
res.send({
status: 200,
msg: "登陆成功!",
token: "Bearer " + token,
});
});
};
5.2、配置解析 Token 中间件
- 安装解析 Token 的中间件
npm i express-jwt@7.7.5
- 在app.js 路由之前,配置解析 Token 的中间件
// 导入 express-jwt 并解构
const { expressjwt: jwt } = require("express-jwt");
// 密钥
const { secretKey } = require("./config");
// 使用 express-jwt 这个中间件,排除注册和登录
app.use(
jwt({ secret: secretKey, algorithms: ["HS256"] }).unless({
path: [/^\/user/],
})
);
项目地址:https://gitee.com/GodLovesYou/express-login-registry-service?_from=gitee_search