目录

一.基于Nodejs+mysql+html实现登录注册功能模块实现思路

1. 环境搭建

2. 设计数据库模型

3. 设置服务器

4. 创建登录和注册页面

5. 处理表单提交

二.后端具体实现步骤

1.初始化项目

1.2.配置cors跨域 

1.3. 配置解析表单数据的中间件 

1.4. 创建路由相关的文件夹

1.5.初始化路由 

1.7. 将路由模块中的处理函数抽离出来

2.具体实现登录注册代码

2.1.新建user数据表

2.2. 安装并配置mysql

2.3. 安装并导入用户密码加密依赖

2.4. 注册模块处理函数完整代码

2.5. 安装生成 Token 字符串的包

2.6. 登录模块处理函数完整代码

 2.7.配置解析token的中间件

三.前端具体实现步骤

1.新建 html 文件夹作为项目根目录,并在项目根目录下创建login.html与register.html

2.注册具体实现代码

3.登录具体实现代码 


一.基于Nodejs+mysql+html实现登录注册功能模块实现思路

1. 环境搭建

  • 安装 Node.js: 确保你的开发环境中已经安装了 Node.js。
  • 创建项目目录: 创建一个新的项目目录,并在该目录中初始化一个新的 Node.js 项目。
  • 安装依赖: 使用 npm 安装必要的依赖包,如 Express(一个流行的 Node.js Web 应用框架)、mysql(数据库)、bcrypt(密码加密库)等。

2. 设计数据库模型

  • 选择数据库: 你可以选择任何支持 Node.js 的数据库,比如 mysql。
  • 设计用户模型: 用户模型至少应该包括用户名、密码等字段。

3. 设置服务器

  • 安装 Express: 使用 npm 安装 Express。
  • 创建服务器: 使用 Express 创建一个基本的 HTTP 服务器。

4. 创建登录和注册页面

  • HTML 页面: 创建登录和注册的 HTML 表单页面。
  • 路由: 使用 Express 设置路由来处理登录和注册的请求。

5. 处理表单提交

  • 密码加密: 使用 bcrypt 对用户密码进行哈希处理,以增强安全性。
  • 存储用户: 将经过验证的用户数据存储到数据库中。
  • 处理登录: 检查用户名和密码是否匹配数据库中的记录。

二.后端具体实现步骤

1.初始化项目

1.1.创建项目

  • 新建 node_api 文件夹作为项目根目录,并在项目根目录中打开cmd或PowerShell运行如下的命令,初始化包管理配置文件: 
    npm init -y
  • 运行如下的命令,安装 express框架:
    npm i express
  • vscode打开项目,在项目根目录中新建 app.js 作为整个项目的入口文件,并初始化如下的代码:
    // 导入express
    const express = require('express')
    // 创建express实例
    const app = express()
    
    
    // 启动服务器
    app.listen(3000, () => {
        console.log('server running at http://localhost:3000')
    });

1.2.配置cors跨域 

  • 运行如下的命令,安装cros中间件:
    npm i cors
  • 在 app.js 中导入并配置 cors 中间件:
    //注册跨域中间件
    const cors = require('cors')
    app.use(cors())

1.3. 配置解析表单数据的中间件 

  • 配置解析 application/x-www-form-urlencoded 格式的表单数据的中间件:

    extended: false 表示使用简化的 URL 编码解析器,它只能解析键值对,并且每个键只能有一个值。这意味着如果表单中有重复的字段名,只有最后一个会被解析并保存。如果extended: true,那么会使用一个更为灵活的解析器,它可以解析嵌套的对象(例如,a[b][c]=d 这样的键),并且可以处理重复的字段名,将它们作为一个数组来保存。

  • // 注册解析表单数据的中间件
    app.use(express.urlencoded({extended:false}))

1.4. 创建路由相关的文件夹

  • 在项目根目录下,新建 router 文件夹,用来存放所有的路由模块,路由模块中,只存放客户端的请求与处理函数之间的映射关系
  • 在项目根目录中,新建 router_handler 文件夹,用来存放所有的路由处理函数模块,路由处理函数模块中,专门负责存放每个路由对应的处理函数

1.5.初始化路由 

  • 在 router 文件夹中,新建 user.js 文件,作为用户的路由模块
    // 引入express
    const express = require('express');
    // 创建用户模块
    const router = express.Router();
    
    // 注册
    router.post('/register', (req,res)=>{
        res.send('注册成功')
    });
    // 登录
    router.post('/login', (req,res)=>{
        res.send('登录成功')
    });
    // 导出路由
    module.exports = router;
  • 在app.js内导入并使用用户路由模块
      // 导入用户路由模块
    const routeruser = require('./router/use')
    app.use('/api',routeruser)

    1.6. 将路由模块中的处理函数抽离出来

  • router_handler文件夹中,新建 userhandle.js 文件,作为用户的路由处理函数模块
    /*
     * 在这里定义和用户相关的路由处理函数,供 /router/user.js 模块进行调用
     */
    // 用户注册处理函数
    exports.register = (req, res) => {
        res.send('注册成功')
    }
    // 用户登录处理函数
    exports.login = (req, res) => {
        res.send('登录成功')
    }
  • 在  /router/user.js 中/router_handler/userhandle.js ,并调用对应的处理函数
    // 引入express
    const express = require('express');
    // 创建用户模块
    const router = express.Router();
    
    // 导入用户处理函数
    const routerhandle = require('../routerhandle/userhandle');
    
    // 注册
    router.post('/register', routerhandle.register);
    // 登录
    router.post('/login', routerhandle.login);
    // 导出路由
    module.exports = router;

    2.具体实现登录注册代码

2.1.新建user数据表

 

2.2. 安装并配置mysql

  • 运行如下命令,安装 mysql 模块:
    npm i mysql
  • 在项目根目录中新建/db/index.js文件,并创建数据库的连接对象:

2.3. 安装并导入用户密码加密依赖

  • 运行如下命令,安装 bcryptjs 依赖:
    npm i bcryptjs@2.4.3

2.4. 注册模块处理函数完整代码

// 引入数据库
const mysql = require('../db/mysql')
//导入bcryptjs加密库
const bcrypt = require('bcryptjs')

// 注册
exports.register = (req, res) => {
    // 获取客户端提交到服务器的用户信息
    const userinfo = req.body;
    // 判断用户名密码是否为空
    if (!userinfo.username || !userinfo.password) {
        return res.send({
            code: 1,
            msg: '用户名或密码不能为空'
        })
    }
    // 查询用户名是否被占用
    const registermysql = "select * from node_use where username = ?"
    mysql.query(registermysql, userinfo.username, (err, result) => {
        if (err) {
            return res.send({
                code: 1,
                msg: err.message
            })
        }
        if (result.length > 0) {
            return res.send({
                code: 1,
                msg: '用户名已存在'
            })
        }
        // 对密码进行加密
        userinfo.password = bcrypt.hashSync(userinfo.password, 10)
        // 插入数据
        const regmysql = "insert into node_use set ?"
        // 执行sql语句
        mysql.query(regmysql, { username: userinfo.username, password: userinfo.password }, (err, result) => {
            if (err) {
                res.send({
                    code: 1,
                    mes: err.message
                })
            }
            res.send({
                code: 0,
                msg: '注册成功'
            })
        })

    })
}

2.5. 安装生成 Token 字符串的包

  • 运行如下命令,安装生成 Token 字符串的包
    npm i jsonwebtoken

2.6. 登录模块处理函数完整代码

// 引入数据库
const mysql = require('../db/mysql')
//导入bcryptjs加密库
const bcrypt = require('bcryptjs')
// 导入jwt
const jwt = require('jsonwebtoken')


exports.login = (req, res) => {
    // 获取客户端提交到服务器的用户信息
    const logininfo = req.body;
    // 判断用户名密码是否为空
    if (!logininfo.username || !logininfo.password) {
        return res.send({
            code: 1,
            msg: '用户名或密码不能为空'
        })
    }
    // 查询用户名是否被占用
    const loginmysql = "select * from node_use where username = ?"
    // 执行sql语句
    mysql.query(loginmysql, logininfo.username, (err, result) => {
        if (err) {
            return res.send({
                code: 1,
                msg: err.message
            })
        }
        if (result.length !== 1) {
            return res.send({
                code: 1,
                msg: '用户名不存在'
            })
        }
        // 判断密码是否正确
        const compareResult = bcrypt.compareSync(logininfo.password, result[0].password)
        if (!compareResult) {
            return res.send({
                code: 1,
                msg: '密码错误'
            })
        }
        // 剔除user中的password属性
        const user = { ...result[0], password: '' }
        // 生成token
        const tokenStr = jwt.sign(user, 'safsaf')
        res.send({
            code: 0,
            msg: '登录成功',
            token: tokenStr
        })

    }
    )
}

 2.7.配置解析token的中间件

  • 运行如下的命令,安装解析 Token的中间件
    // 注意这里必须加版本
    npm i express-jwt@5.3.3
    
  • 在 app.js 中注册路由之前,配置解析 Token 的中间件
    // 导入express-jwt
    const jwt = require('express-jwt')
    
    // 解析token的中间件
    app.use(jwt({secret:'safsaf'}).unless({path:['/api/login','/api/register']}))
    
    
    // unless({path:['/api/login','/api/register']})) 
    // 除了登录和注册之外的接口都需要验证身份
    
    // 必须写在导入路由模块之前
  • 在 app.js 中的 误级别中间件 里面,捕获并处理 Token 认证失败后的错误
    // 捕获身份认证失败的中间件
    app.use(function (err, req, res, next) {
        // 捕获身份认证失败的中间件
        if (err.name === "UnauthorizedError") {
          return res.send({
            code:1,
            msg:'身份认证失败'
          });
        }
      });
    
    // 必须写在导入路由模块之前

三.前端具体实现步骤

1.新建 html 文件夹作为项目根目录,并在项目根目录下创建login.html与register.html

注意

2.注册具体实现代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>注册</title>
    <style>
        .login {
            width: 50%;
            height: 400px;
            margin: 150px auto;
            background-color: rgb(212, 205, 205);
        }

        .name {
            width: 60%;
            height: 80px;
            margin: 10px auto;
            line-height: 80px;
        }

        .but {
            width: 25%;
            height: 50px;
            margin: 10px auto;
            line-height: 50px;
        }

        button {
            width: 80px;
            height: 40px;
            margin: 10px auto;
            background-color: rgb(102, 177, 255);
            border: none;
        }
    </style>
</head>

<body>
    <div class="login">
        <h1 style="text-align: center;padding-top: 30px;">欢迎注册</h1>
        <div class="name" style="margin-top: 60px;">
            <span style="margin-left: 10px;font-weight: 600;font-size: 20px;">用户名:</span>
            <input type="text" style="width: 70%;height: 50px;font-size: 18px;" id="username">
        </div>
        <div class="name">
            <span style="margin-left: 10px;font-weight: 600;font-size: 20px;">密 &nbsp;&nbsp;码:</span>
            <input type="password" style="width: 70%;height: 50px;font-size: 18px;" id="password">
        </div>
        <div class="but">
            <button style="float: left;" id="log">注册</button>
            <button style="float: right;" id="back">取消</button>
        </div>

    </div>
    </div>


    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
        // 注册按钮事件
        document.querySelector('#log').addEventListener('click', async () => {
            // 创建 XMLHttpRequest 对象
            var xhr = new XMLHttpRequest();
            // 请求方式以及url
            xhr.open('POST', 'http://localhost:3000/rest/register', true);
            // 将默认json格式转换为application/x-www-form-urlencoded格式
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            const params = new URLSearchParams();
            params.append("username", username.value);
            params.append("password", password.value);
            // 发送请求并携带参数
            xhr.send(params);
            // 请求监听
            xhr.addEventListener('loadend', () => {
                const data = JSON.parse(xhr.response)
                if (data.code === 0) {
                    alert(data.msg)
                    window.location.href = 'login.html'
                } else {
                    alert(data.msg)
                }
            })
        })

        // 取消按钮事件
        document.querySelector('#back').addEventListener('click', () => {
            window.location.href = 'login.html'
        })
    </script>
</body>

</html>

3.登录具体实现代码 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>登录</title>
    <style>
        .login {
            width: 50%;
            height: 400px;
            margin: 150px auto;
            background-color: rgb(212, 205, 205);
        }

        .name {
            width: 60%;
            height: 80px;
            margin: 10px auto;
            line-height: 80px;
        }

        .but {
            width: 25%;
            height: 50px;
            margin: 10px auto;
            line-height: 50px;
        }

        button {
            width: 80px;
            height: 40px;
            margin: 10px auto;
            background-color: rgb(102, 177, 255);
            border: none;
        }
    </style>
</head>

<body>
    <div class="login">
        <h1 style="text-align: center;padding-top: 30px;">欢迎登录</h1>
        <div class="name" style="margin-top: 60px;">
            <span style="margin-left: 10px;font-weight: 600;font-size: 20px;">用户名:</span>
            <input type="text" style="width: 70%;height: 50px;font-size: 18px;" id="username">
        </div>
        <div class="name">
            <span style="margin-left: 10px;font-weight: 600;font-size: 20px;">密 &nbsp;&nbsp;码:</span>
            <input type="password" style="width: 70%;height: 50px;font-size: 18px;" id="password">
        </div>
        <div class="but">
            <button style="float: left;" id="log">登录</button>
            <button style="float: right;" id="reg">注册</button>
        </div>

    </div>
    </div>
    <script>
        // 登录按钮事件
        document.querySelector('#log').addEventListener('click', async () => {
            // 创建 XMLHttpRequest 对象
            var xhr = new XMLHttpRequest();
            // 请求方式以及url
            xhr.open('POST', 'http://localhost:3000/rest/login', true);
            // 设置请求头
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            // 将默认json格式转换为application/x-www-form-urlencoded格式
            const params = new URLSearchParams();
            params.append("username", username.value);
            params.append("password", password.value);
            // 发送请求并携带参数
            xhr.send(params);
            // 请求监听
            xhr.addEventListener('loadend', () => {
                const data = JSON.parse(xhr.response)
                if (data.code === 0) {
                    alert(data.msg)
                    window.location.href = 'index.html'
                } else {
                    alert(data.msg)
                }
            })
        })
        // 注册按钮事件
        document.querySelector('#reg').addEventListener('click', () => {
            window.location.href = 'register.html'
        })


    </script>
</body>

</html>

!!!前端发送网络请求部分使用的是原生Ajax,也可使用三方库axios

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐