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 进行单元测试。这个项目可以作为一个基础的示例,帮助你进一步扩展和完善用户登录功能。

相关推荐
Arva .14 分钟前
MySQL 的存储引擎
数据库·mysql
Logic10120 分钟前
《Mysql数据库应用》 第2版 郭文明 实验5 存储过程与函数的构建与使用核心操作与思路解析
数据库·sql·mysql·学习笔记·计算机网络技术·形考作业·国家开放大学
LYFlied33 分钟前
【一句话概述】Webpack、Vite、Rollup 核心区别
前端·webpack·node.js·rollup·vite·打包·一句话概述
小二·35 分钟前
MyBatis基础入门《十六》企业级插件实战:基于 MyBatis Interceptor 实现 SQL 审计、慢查询监控与数据脱敏
数据库·sql·mybatis
bing.shao35 分钟前
Golang WaitGroup 踩坑
开发语言·数据库·golang
专注VB编程开发20年43 分钟前
C#内存加载dll和EXE是不是差不多,主要是EXE有入口点
数据库·windows·microsoft·c#
小二·1 小时前
MyBatis基础入门《十二》批量操作优化:高效插入/更新万级数据,告别慢 SQL!
数据库·sql·mybatis
何中应1 小时前
【面试题-6】MySQL
数据库·后端·mysql·面试题
路遥_131 小时前
银河麒麟 V10 安装部署瀚高数据库 HighGoDB 4.5 全流程(统信UOS Server 20同理)
数据库
TDengine (老段)1 小时前
从关系型数据库到时序数据库的思维转变
大数据·数据库·mysql·时序数据库·tdengine·涛思数据·非关系型数据库