2024年在线市场平台的11大最佳支付解决方案
node.js + express + docker + mysql + jwt 实现用户管理restful api
2024-11-28
今天我们用node.js + express + docker + mysql + jwt来搞一个简单版的用户管理restful api,里面有基础的用户注册、用户登录和获取用户信息的功能。其中用到了express的路由,使用express-validator作为表单验证器,用docker运行mysql容器,密码的加密,jwt生成用户token等等。下面来搞起来
用到的技术
第一步:创建项目目录
mkdir nodejs-auth-mysql-rest-api
cd nodejs-auth-mysql-rest-api
npm init -y
安装依赖
npm install express express-validator mysql body-parser jsonwebtoken bcryptjs cors --save
- express
- 启动基本的http服务
- express-validator
- 用来验证表单是否合法
- mysql
- 连接mysql数据库,存储数据,查询数据
- body-parser
- 解析post请求体的数据
- jsonwebtoken
- 用于生成jwt的token
- bcryptjs
- 加密用户注册的密码
- cors
- 允许跨域的请求访问
第二步:创建数据库和表
这里我不用在电脑上去安装mysql数据库,我们使用docker的方式在本机上运行一个mysql容器,需要熟悉一些基本的docker使用。
创建数据文件夹
mkdir data
创建mysql容器
docker run -v "$PWD/data":/var/lib/mysql --name dev-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
- docker run
- 运行docker容器
- -v “$PWD/data”:/var/lib/mysql
- 将容器内的数据存储目录映射到宿主机的目录,避免容器关闭导致的数据丢失
- –name dev-mysql
- 容器名称
- -p 3306:3306
- 将容器内的3306端口映射到宿主机上,这里我是为了方便,正常是不会这样映射,因为很危险。
- -e MYSQL_ROOT_PASSWORD=123456
- 将root密码设置为123456
- -d
- 将容器在后台运行
- mysql:5.7
- 容器的镜像和镜像版本
查看运行容器
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b1808287e831 mysql:5.7 "docker-entrypoint.s…" 15 seconds ago Up 12 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp dev-mysql
停止容器
docker stop b1808287e831
查看所有容器
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b1808287e831 mysql:5.7 "docker-entrypoint.s…" 15 minutes ago Exited (0) 10 seconds ago dev-mysql
启动容器
docker start b1808287e831
创建数据库和表
在目录中创建database.sql
,用户创建数据表
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`email` varchar(50) NOT NULL,
`password` varchar(200) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY email (email)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
执行下面命令在容器内创建数据库和表
# 将sql文件拷贝进容器内
docker cp $PWD/database.sql b1808287e831:/database.sql
# 进入容器内
docker exec -it b1808287e831 bin/bash
# 连接mysql 输入密码
mysql -u root -p
# 显示所有数据数据库
show databases;
# 创建数据库
create database `node-app`;
# 使用数据库
use `node-app`;
# 导入数据表
source /database.sql;
# 退出mysql
exit;
# 退出容器
exit;
第三步:在nodejs中连接数据库
创建dbConnection.js
const mysql = require('mysql');
const conn = mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: '123456',
database: 'node-app'
});
conn.connect(function(err) {
if (err) throw err;
console.log('数据库连接成功');
});
module.exports = conn;
测试是否能连接成功
node dbConnection.js
# 数据库连接成功
第四步:创建express服务
创建server.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const indexRouter = require('./router.js');
const app = express();
app.use(express.json());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cors());
app.use('/api', indexRouter);
// 处理错误
app.use((err, req, res, next) => {
// console.log(err);
err.statusCode = err.statusCode || 500;
err.message = err.message || "Internal Server Error";
res.status(err.statusCode).json({
message: err.message,
});
});
app.listen(3000,() => console.log(`服务启动成功:http://localhost:3000`));
第五步:创建路由和验证器
创建validation.js
文件
const { check } = require('express-validator');
exports.signupValidation = [
check('name', '请输入用户名').not().isEmpty(),
check('email', '请输入合法的邮箱').isEmail(),
check('password', '密码至少是6位哦').isLength({ min: 6 })
]
exports.loginValidation = [
check('email', '请输入合法的邮箱').isEmail(),
check('password', '密码至少是6位哦').isLength({ min: 6 })
]
创建router.js文件
const express = require('express');
const router = express.Router();
const db = require('./dbConnection');
const { signupValidation, loginValidation } = require('./validation');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const JWT_SECRET = 'my-secret'
router.post('/register', signupValidation, (req, res, next) => {
db.query(
`SELECT * FROM users WHERE LOWER(email) = LOWER(${db.escape(
req.body.email
)});`,
(err, result) => {
if (result.length) {
return res.status(409).send({
msg: '邮箱已被注册'
});
} else {
// 如果可以注册,
bcrypt.hash(req.body.password, 10, (err, hash) => {
if (err) {
return res.status(500).send({
msg: err
});
} else {
// 密码加密后,存入数据库
db.query(
`INSERT INTO users (name, email, password) VALUES ('${req.body.name}', ${db.escape(
req.body.email
)}, ${db.escape(hash)})`,
(err, result) => {
if (err) {
return res.status(400).send({
msg: err
});
}
return res.status(201).send({
msg: '用户注册成功'
});
}
);
}
});
}
}
);
});
router.post('/login', loginValidation, (req, res, next) => {
db.query(
`SELECT * FROM users WHERE email = ${db.escape(req.body.email)};`,
(err, result) => {
// 用户不存在
if (err) {
// throw err;
return res.status(400).send({
msg: err
});
}
if (!result.length) {
return res.status(401).send({
msg: '用户名或密码错误'
});
}
// 检查密码是否正确
bcrypt.compare(
req.body.password,
result[0]['password'],
(bErr, bResult) => {
// 密码错误
if (bErr) {
// throw bErr;
return res.status(401).send({
msg: '用户名或密码错误'
});
}
if (bResult) {
const token = jwt.sign({ id: result[0].id }, JWT_SECRET, { expiresIn: '1h' });
db.query(
`UPDATE users SET last_login = now() WHERE id = '${result[0].id}'`
);
return res.status(200).send({
msg: '登陆成功',
token,
user: result[0]
});
}
return res.status(401).send({
msg: '用户名或密码错误'
});
}
);
}
);
});
router.post('/get-user', signupValidation, (req, res, next) => {
if (
!req.headers.authorization ||
!req.headers.authorization.startsWith('Bearer') ||
!req.headers.authorization.split(' ')[1]
) {
return res.status(422).json({
message: "缺少Token",
});
}
const theToken = req.headers.authorization.split(' ')[1];
const decoded = jwt.verify(theToken, JWT_SECRET);
db.query('SELECT * FROM users where id=?', decoded.id, function (error, results, fields) {
if (error) throw error;
return res.send({ error: false, data: results[0], message: '请求成功' });
});
});
module.exports = router;
第六步:运行Express服务
安装nodemon
npm install nodemon --save-dev
修改package.json
"scripts": {
"start": "nodemon server.js"
},
运行项目
npm start
# 服务启动成功:http://localhost:3000
# 数据库连接成功
第七步:使用postman测试
注册用户
POST - http://localhost:3000/api/register
查看数据库是否有数据
登陆
POST - http://localhost:3000/api/login
获取用户信息
POST - http://localhost:3000/api/get-user
源码
Github:https://github.com/cmdfas/nodejs-auth-mysql-rest-api
本文章转载微信公众号@小帅的编程笔记
同话题下的热门内容