- 总体架构
NodeJs是一种基于事件驱动、非阻塞I/O模型的JavaScript后端运行环境,它提供了众多的系统模块和第三方模块,以及一个强大的包管理工具npm。MySQL是一种流行的关系型数据库管理系统,提供了完善的数据库设计和管理工具,以及一套丰富的SQL语言和API。
注册登录功能的实现,主要涉及以下几个环节:
- 用户信息的采集和存储;
- 用户名和密码的加密处理;
- 用户名和密码的校验和匹配;
- 登录状态的管理和维护。
具体来说,可以采用NodeJs的Express框架搭建Web服务端,使用MySQL的NodeJs驱动模块mysql模块连接和操作数据库,实现前端和后端的交互和数据传输。
- 具体步骤
2.1 初始化项目
在本地创建一个新的项目文件夹,进入该文件夹,在命令行中输入以下命令:
npm init
按照提示完成基本信息的填写,生成一个package.json文件,记录项目依赖的模块和版本号。
2.2 安装依赖模块
本次项目需要用到以下模块:
- express:用于搭建Web框架和处理HTTP请求;
- body-parser:用于解析HTTP request body 中的数据,如POST请求中的数据;
- mysql:用于连接和操作MySQL数据库;
- bcryptjs:用于对用户密码进行加密处理。
可以运行以下命令一键安装:
npm install express body-parser mysql bcryptjs
2.3 创建数据库
在MySQL中创建一个新的数据库(如mydb),用于存储用户信息和登录状态的数据表。可以运行以下命令初始化一个users表:
CREATE TABLE users (
id INT NOT NULL AUTO_INCREMENT,
username VARCHAR(255) UNIQUE NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);
2.4 创建Express应用
在项目根目录下创建一个index.js文件,输入以下代码:
const express = require('express');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const app = express();
// 中间件:解析HTTP请求体中的JSON数据
app.use(bodyParser.json());
// HTTP GET /api/users ==> query all users
app.get('/api/users', (req, res) => {
// TODO: query all users from database and send response
});
// HTTP POST /api/register ==> register a new user
app.post('/api/register', (req, res) => {
// TODO: collect user data from request body, encrypt password, and insert into database
});
// HTTP POST /api/login ==> authenticate user and create session
app.post('/api/login', (req, res) => {
// TODO: collect user data from request body, query user from database, verify password, and create session
});
// HTTP GET /api/logout ==> destroy session
app.get('/api/logout', (req, res) => {
// TODO: destroy session
});
// start the server listening at port 3000
const server = app.listen(3000, () => {
const { address, port } = server.address();
console.log(`Express server listening on http://${address}:${port}`);
});
2.5 连接数据库
在index.js文件中添加如下代码段:
// 数据库连接配置
const dbConfig = {
host: 'localhost',
user: 'root',
password: 'password',
database: 'mydb',
};
// 创建数据库连接池
const dbPool = mysql.createPool(dbConfig);
// 中间件:将数据库连接池添加到Request对象中,方便在路由中使用
app.use((req, res, next) => {
req.dbPool = dbPool;
next();
});
2.6 收集用户信息
在注册和登录路由函数中,需要从HTTP请求对象的body中提取用户名、邮箱和密码等必要信息。可以使用如下代码:
const { username, email, password } = req.body;
接下来,需要对密码进行加密处理,以避免明文存储导致的安全问题。可以使用bcryptjs模块提供的hashSync函数,将明文密码转换为哈希值:
const bcrypt = require('bcryptjs');
const saltRounds = 10;
const hashedPassword = bcrypt.hashSync(password, saltRounds);
2.7 插入数据库
在注册路由函数中,需要将用户信息插入到MySQL数据库的users表中。可以使用如下代码:
const sql = 'INSERT INTO users (username, email, password) VALUES (?, ?, ?)';
const values = [username, email, hashedPassword];
req.dbPool.query(sql, values, (error, results, fields) => {
if (error) {
console.error(error);
res.status(500).send('Internal Server Error');
} else {
console.log(`New user ${username} successfully registered`);
res.send('OK');
}
});
2.8 验证用户身份
在登录路由函数中,需要从MySQL数据库的users表中查询用户名匹配的用户,并验证其密码是否正确。可以使用如下代码:
const sql = 'SELECT * FROM users WHERE username = ? OR email = ?';
const values = [username, email];
req.dbPool.query(sql, values, (error, results, fields) => {
if (error) {
console.error(error);
res.status(500).send('Internal Server Error');
} else if (results.length == 0) {
console.warn(`User ${username} not found`);
res.status(401).send('Invalid username or password');
} else {
const user = results[0];
if (bcrypt.compareSync(password, user.password)) {
console.log(`User ${username} successfully logged in`);
// TODO: create session and send response
} else {
console.warn(`User ${username} entered wrong password`);
res.status(401).send('Invalid username or password');
}
}
});
2.9 保存登录状态
在创建登录成功的Session之后,需要将Session ID保存到客户端的Cookie中,并设置过期时间。可以使用如下代码:
const maxAge = 24 * 60 * 60 * 1000; // session剩余24小时有效期
res.cookie('session_id', sessionId, { maxAge });
同时,需要处理用户访问需要授权的API时的验证逻辑,可以使用如下代码:
// 中间件:验证用户登录状态
app.use('/api', (req, res, next) => {
const sessionId = req.cookies.session_id;
// TODO: verify session
if (isSessionValid) {
next();
} else {
res.status(401).send('Unauthorized');
}
});
- 示例说明
3.1 示例1:注册新用户
在客户端发起HTTP POST请求/ api/register,携带如下数据:
{
"username": "alice",
"email": "alice@example.com",
"password": "123456"
}
服务器收到请求后,从request body中提取数据,对密码进行加密处理,通过MySQL的INSERT语句将用户信息插入到数据库中。
如果成功注册,则返回HTTP响应码200 OK,否则返回HTTP响应码500 Internal Server Error或401 Invalid username or password。
3.2 示例2:登录用户
在客户端发起HTTP POST请求/ api/login,携带如下数据:
{
"username": "alice",
"password": "123456"
}
服务器收到请求后,从request body中提取数据,查询MySQL数据库的users表中是否存在该用户(用username或email匹配),验证密码是否正确。
如果用户名和密码匹配,则创建新的Session,保存Session ID到客户端的Cookie中,返回HTTP响应码200 OK。
如果用户名或密码不匹配,则返回HTTP响应码401 Invalid username or password。
3.3 示例3:访问授权接口
在客户端发起HTTP GET请求/ api/users,访问需要授权的API时,服务器首先检查客户端的Cookie中是否包含有效的Session ID,如果是,则允许访问,否则返回HTTP响应码401 Unauthorized。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:NodeJs+MySQL实现注册登录功能 - Python技术站