Node.js 开发用户登录功能(使用mysql实现)

在 Web 开发中,用户登录功能是一个基础且重要的部分。、

一、环境搭建

在开始开发之前,我们需要搭建好相应的开发环境。以下是所需的工具和库:

  • Node.js:作为 JavaScript 的运行环境,为我们的项目提供支持。
  • mysql2:用于与 MySQL 数据库进行交互的驱动程序。
  • express:一个流行的 Node.js Web 框架,帮助我们快速搭建 Web 应用。
  • ejs:模板引擎,用于生成动态 HTML 页面。
  • mysql:关系型数据库,用于存储用户信息。
  • mocha:测试工具,可用于对代码进行单元测试。

首先,确保你已经安装了 Node.js 和 MySQL。然后,创建一个新的项目目录,并在该目录下初始化 package.json 文件:

bash 复制代码
mkdir user-login-project
cd user-login-project
npm init -y

接着,安装所需的依赖:

bash 复制代码
npm install mysql2 express ejs
npm install --save-dev mocha

二、数据库准备

user_db.sql 文件导入到 MySQL 数据库中。你可以使用以下命令:

bash 复制代码
mysql -u your_username -p your_database_name < user_db.sql

请将 your_username 替换为你的 MySQL 用户名,your_database_name 替换为你要使用的数据库名称。

三、项目结构

为了使项目结构清晰,便于管理和维护,我们采用以下目录结构:

plaintext

复制代码
user-login-project/
├── public/
│   └── styles.css
├── views/
│   ├── login.ejs
│   └── index.ejs
├── models/
│   └── user.js
├── middleware/
│   └── auth.js
├── app.js
├── package.json
└── test/
    └── user.test.js

四、代码实现

4.1 开发登录页面

views 目录下创建 login.html文件,该文件用于显示登录表单。以下是 login.html 的代码:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login</title>
    <link rel="stylesheet" href="/styles.css">
</head>
<body>
    <h1>Login</h1>
    <% if (error) { %>
        <p style="color: red;"><%= error %></p>
    <% } %>
    <form action="/login" method="post">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" required><br>
        <label for="password">Password:</label>
        <input type="password" id="password" name="password" required><br>
        <button type="submit">Login</button>
    </form>
</body>
</html>

views 目录下创建 index.html文件,该文件用于显示首页表单。以下是 index.html 的代码:

html 复制代码
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>首页</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet">
    <style>
        /* 自定义样式 */
        body {
            font-family: 'Inter', sans-serif;
        }
    </style>
</head>
<body class="bg-gray-100 min-h-screen flex flex-col">
<header class="bg-blue-600 text-white py-6 px-8 shadow-md">
    <h1 class="text-3xl font-bold">欢迎 <%= user.name %> 登录成功!</h1>
</header>
<main class="flex-grow container mx-auto py-12 px-4">
    <p class="text-lg text-gray-700 leading-relaxed">这里是首页内容</p>
</main>
<footer class="bg-gray-200 py-6 px-8">
    <a href="/logout" class="text-blue-600 hover:text-blue-800 transition duration-300 ease-in-out">
        <i class="fa-solid fa-right-from-bracket mr-2"></i>退出登录
    </a>
</footer>
</body>
</html>

在这个页面中,我们使用 EJS 模板引擎来动态显示错误信息。如果登录失败,会显示相应的错误提示。

4.2 开发程序入口以及配置

在项目根目录下创建 app.js 文件,这是我们项目的入口文件。以下是 app.js 的代码:

javascript 复制代码
const express = require('express');
const mysql = require('mysql2/promise');
const ejs = require('ejs');
const bodyParser = require('body-parser');
const path = require('path');

const app = express();
const port = 3000;

// 配置模板引擎
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));

// 配置静态文件目录
app.use(express.static(path.join(__dirname, 'public')));

// 解析表单数据
app.use(bodyParser.urlencoded({ extended: true }));

// 创建数据库连接池
const pool = mysql.createPool({
    host: 'localhost',
    user: 'your_username',
    password: 'your_password',
    database: 'your_database_name',
    waitForConnections: true,
    connectionLimit: 10,
    queueLimit: 0
});

// 登录页面
app.get('/login', (req, res) => {
    res.render('login', { error: null });
});

// 处理登录请求
app.post('/login', async (req, res) => {
    const { username, password } = req.body;
    try {
        const [rows] = await pool.execute('SELECT * FROM users WHERE username = ? AND password = ?', [username, password]);
        if (rows.length > 0) {
            res.redirect('/');
        } else {
            res.render('login', { error: 'Invalid username or password' });
        }
    } catch (error) {
        console.error(error);
        res.render('login', { error: 'Database error' });
    }
});

// 首页
app.get('/', (req, res) => {
    res.render('index');
});

// 启动服务器
app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
});

在 app.js 中,我们完成了以下几个重要的配置:

  • 配置 EJS 模板引擎,指定视图文件的目录。
  • 配置静态文件目录,使浏览器可以访问 public 目录下的静态资源。
  • 创建 MySQL 数据库连接池,用于与数据库进行交互。
  • 定义了登录页面和处理登录请求的路由。如果登录成功,重定向到首页;如果登录失败,重新渲染登录页面并显示错误信息。

4.3 开发数据模型

models 目录下创建 user.js 文件,该文件用于处理与用户相关的数据操作。以下是 user.js 的代码:

javascript 复制代码
const mysql = require('mysql2/promise');

const pool = mysql.createPool({
    host: 'localhost',
    user: 'your_username',
    password: 'your_password',
    database: 'your_database_name',
    waitForConnections: true,
    connectionLimit: 10,
    queueLimit: 0
});

const findUserByUsernameAndPassword = async (username, password) => {
    try {
        const [rows] = await pool.execute('SELECT * FROM users WHERE username = ? AND password = ?', [username, password]);
        return rows[0];
    } catch (error) {
        console.error(error);
        return null;
    }
};

module.exports = {
    findUserByUsernameAndPassword
};

user.js 中,我们定义了一个 findUserByUsernameAndPassword 函数,用于根据用户名和密码查找用户信息。如果找到匹配的用户,返回该用户的信息;否则返回 null

4.4 开发中间件

middleware 目录下创建 auth.js 文件,该文件用于验证用户登录信息。以下是 auth.js 的代码:

javascript 复制代码
const { findUserByUsernameAndPassword } = require('../models/user');

const authenticateUser = async (req, res, next) => {
    const { username, password } = req.body;
    const user = await findUserByUsernameAndPassword(username, password);
    if (user) {
        req.user = user;
        next();
    } else {
        res.render('login', { error: 'Invalid username or password' });
    }
};

module.exports = {
    authenticateUser
};

auth.js 中,我们定义了一个 authenticateUser 中间件,用于验证用户的登录信息。如果验证成功,将用户信息存储在 req.user 中,并调用 next() 继续处理请求;如果验证失败,重新渲染登录页面并显示错误信息。

五、测试(可选)

为了确保代码的正确性,我们可以使用 Mocha 进行单元测试。在 test 目录下创建 user.test.js 文件,以下是 user.test.js 的代码

javascript 复制代码
const assert = require('assert');
const { findUserByUsernameAndPassword } = require('../models/user');

describe('User Model', () => {
    it('should find a user by username and password', async () => {
        const user = await findUserByUsernameAndPassword('testuser', 'testpassword');
        assert.ok(user);
    });
});

在 package.json 中添加测试脚本:

bash 复制代码
{
    "scripts": {
        "test": "mocha"
    }
}

运行测试:

bash 复制代码
npm test

六、运行项目

在项目根目录下运行以下命令启动服务器:

bash 复制代码
node app.js

然后在浏览器中访问 http://localhost:3000/login 即可看到登录页面。

七、总结

通过以上步骤,我们成功地基于 Node.js 开发了一个简单的用户登录功能。在开发过程中,我们使用了 Express 框架搭建 Web 应用,使用 EJS 模板引擎生成动态 HTML 页面,使用 MySQL 数据库存储用户信息,并使用 Mocha 进行单元测试。这个项目可以作为一个基础的示例,帮助你进一步扩展和完善用户登录功能。

相关推荐
jnrjian9 小时前
text index 查看index column index定义 index 刷新频率 index视图
数据库·oracle
瀚高PG实验室9 小时前
审计策略修改
网络·数据库·瀚高数据库
言慢行善10 小时前
sqlserver模糊查询问题
java·数据库·sqlserver
韶博雅10 小时前
emcc24ai
开发语言·数据库·python
有想法的py工程师10 小时前
PostgreSQL 分区表排序优化:Append Sort 优化为 Merge Append
大数据·数据库·postgresql
喵了几个咪10 小时前
如何在 Superset Docker 容器中安装 MySQL 驱动
mysql·docker·容器·superset
迷枫71210 小时前
达梦数据库的体系架构
数据库·oracle·架构
夜晚打字声11 小时前
9(九)Jmeter如何连接数据库
数据库·jmeter·oracle
Chasing__Dreams11 小时前
Mysql--基础知识点--95--为什么避免使用长事务
数据库·mysql