在当今的Web开发领域,Node.js因其高效和非阻塞I/O模型而广受欢迎。结合Express框架和MySQL数据库,我们可以快速构建一个完整的后端服务。本文将带你一步步实现一个简单的用户注册和登录系统。
一、环境准备
首先,确保你已经安装了Node.js和MySQL。然后创建一个新项目:
mkdir node-auth-system
cd node-auth-system
npm init -y
安装必要的依赖:
npm install express mysql2 body-parser bcryptjs jsonwebtoken cors
-
express: Node.js的Web框架 -
mysql2: MySQL数据库驱动 -
body-parser: 解析请求体 -
bcryptjs: 密码加密 -
jsonwebtoken: 生成JWT令牌 -
cors: 处理跨域请求
二、项目结构
node-auth-system/
├── config/
│ └── db.js # 数据库配置
├── controllers/
│ ├── auth.js # 认证逻辑
├── models/
│ └── user.js # 用户模型
├── routes/
│ └── auth.js # 认证路由
├── app.js # 主应用文件
└── package.json
三、数据库配置
首先在MySQL中创建数据库和用户表:
CREATE DATABASE auth_system;
USE auth_system;
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
然后在config/db.js中配置数据库连接:
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
host: 'localhost',
user: 'root', // 替换为你的MySQL用户名
password: 'password', // 替换为你的MySQL密码
database: 'auth_system',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
module.exports = pool;
四、创建Express应用
在app.js中设置基础Express应用:
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const authRoutes = require('./routes/auth');
const app = express();
// 中间件
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// 路由
app.use('/api/auth', authRoutes);
// 错误处理
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
五、实现用户模型
在models/user.js中创建用户模型:
const pool = require('../config/db');
const bcrypt = require('bcryptjs');
class User {
static async findByUsername(username) {
const [rows] = await pool.query('SELECT * FROM users WHERE username = ?', [username]);
return rows[0];
}
static async findByEmail(email) {
const [rows] = await pool.query('SELECT * FROM users WHERE email = ?', [email]);
return rows[0];
}
static async create(userData) {
const { username, email, password } = userData;
const hashedPassword = await bcrypt.hash(password, 10);
const [result] = await pool.query(
'INSERT INTO users (username, email, password) VALUES (?, ?, ?)',
[username, email, hashedPassword]
);
return { id: result.insertId, username, email };
}
static async comparePasswords(plainPassword, hashedPassword) {
return await bcrypt.compare(plainPassword, hashedPassword);
}
}
module.exports = User;
六、实现认证控制器
在controllers/auth.js中处理注册和登录逻辑:
const jwt = require('jsonwebtoken');
const User = require('../models/user');
const JWT_SECRET = 'your_jwt_secret_key'; // 生产环境应该使用环境变量
exports.register = async (req, res, next) => {
try {
const { username, email, password } = req.body;
// 检查用户名或邮箱是否已存在
const existingUser = await User.findByUsername(username) || await User.findByEmail(email);
if (existingUser) {
return res.status(400).json({ message: 'Username or email already exists' });
}
// 创建新用户
const newUser = await User.create({ username, email, password });
res.status(201).json({
message: 'User created successfully',
user: newUser
});
} catch (err) {
next(err);
}
};
exports.login = async (req, res, next) => {
try {
const { username, password } = req.body;
// 查找用户
const user = await User.findByUsername(username);
if (!user) {
return res.status(401).json({ message: 'Invalid credentials' });
}
// 验证密码
const isMatch = await User.comparePasswords(password, user.password);
if (!isMatch) {
return res.status(401).json({ message: 'Invalid credentials' });
}
// 生成JWT令牌
const token = jwt.sign(
{ userId: user.id, username: user.username },
JWT_SECRET,
{ expiresIn: '1h' }
);
res.json({
message: 'Login successful',
token,
user: { id: user.id, username: user.username, email: user.email }
});
} catch (err) {
next(err);
}
};
七、设置路由
在routes/auth.js中定义认证路由:
const express = require('express');
const router = express.Router();
const authController = require('../controllers/auth');
// 注册路由
router.post('/register', authController.register);
// 登录路由
router.post('/login', authController.login);
module.exports = router;
八、测试API
现在你可以使用Postman或其他API测试工具来测试你的服务:
1、注册用户:
POST http://localhost:3000/api/auth/register
Content-Type: application/json
{
"username": "testuser",
"email": "test@example.com",
"password": "password123"
}
2、用户登录:
POST http://localhost:3000/api/auth/login
Content-Type: application/json
{
"username": "testuser",
"password": "password123"
}
成功登录后,你将收到一个JWT令牌,可以在后续的请求中使用它来进行身份验证。
九、安全注意事项
在生产环境中,务必将JWT密钥存储在环境变量中
使用HTTPS来保护传输中的数据
考虑实现密码强度要求和账户锁定机制
添加输入验证以防止SQL注入
定期更新依赖库以修复安全漏洞
十、总结
通过本文,我们使用Node.js、Express和MySQL构建了一个完整的用户认证系统。这个系统包含了用户注册、登录和基本的密码加密功能。你可以在此基础上进一步扩展,比如添加密码重置、电子邮件验证、角色权限管理等功能。
这种技术栈组合非常适合中小型Web应用,它提供了良好的性能和开发效率。希望这篇文章能帮助你快速入门Node.js后端开发!
如果你喜欢这篇文章,欢迎关注我的公众号【前端的那点事情】,获取更多精彩内容!