要实现一个登录接口,并在用户未注册时直接注册他们,您需要在您的 Express 应用中处理两个逻辑路径:一个是验证用户是否已存在(登录),另一个是在用户不存在时创建新用户(注册)。以下是一个简化的实现示例,它结合了登录和注册功能:
const express = require('express');
const mysql = require('mysql2/promise');
const bodyParser = require('body-parser');
const bcrypt = require('bcrypt'); // 用于密码哈希
const saltRounds = 10; // 密码哈希的盐轮数
const app = express();
const port = 3000;
// 配置 MySQL 连接池
const pool = mysql.createPool({
host: 'localhost',
user: 'root', // 根据实际情况修改
password: 'your_password', // 根据实际情况修改
database: 'login_db'
});
// 使用 body-parser 中间件解析 JSON 请求体
app.use(bodyParser.json());
// 登录/注册接口
app.post('/auth', async (req, res) => {
const { username, password } = req.body;
if (!username || !password) {
return res.status(400).json({ message: 'Username and password are required' });
}
try {
const connection = await pool.getConnection();
// 检查用户是否存在
const [rows] = await connection.execute('SELECT * FROM users WHERE username = ?', [username]);
if (rows.length > 0) {
// 用户已存在,验证密码
const hashedPassword = rows[0].password;
const isMatch = await bcrypt.compare(password, hashedPassword);
if (isMatch) {
return res.status(200).json({ message: 'Login successful', user: { username: rows[0].username } });
} else {
return res.status(401).json({ message: 'Invalid username or password' });
}
} else {
// 用户不存在,注册新用户
const hashedPassword = await bcrypt.hash(password, saltRounds);
await connection.execute('INSERT INTO users (username, password) VALUES (?, ?)', [username, hashedPassword]);
return res.status(201).json({ message: 'User registered and logged in successfully', user: { username } });
}
connection.release();
} catch (err) {
console.error(err);
return res.status(500).json({ message: 'Internal server error' });
}
});
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
在这个示例中,我们做了以下事情:
- 使用
mysql2/promise
而不是mysql2
来支持基于 Promise 的数据库操作,这使得异步代码更加简洁。 - 引入了
bcrypt
库来哈希密码,以确保密码在数据库中以安全的形式存储。 - 创建了一个
/auth
路由来处理登录和注册请求。 - 在接收到请求后,首先检查用户是否已存在。
- 如果用户存在,则验证提供的密码是否与存储的哈希密码匹配。
- 如果用户不存在,则使用提供的用户名和密码(经过哈希处理)创建一个新用户。
- 使用了 MySQL 连接池来管理数据库连接,以提高性能和资源利用率。
请注意,这个示例是为了教学目的而简化的,并且在实际生产环境中需要更多的安全措施,比如验证输入、防止 SQL 注入(尽管在这个例子中我们使用了参数化查询来避免这个问题)、处理并发请求等。此外,您可能还需要实现密码重置、账户锁定、日志记录等功能。