koa2实现登录注册功能的示例代码

yizhihongxing

下面是针对“koa2实现登录注册功能的示例代码”的完整攻略。

前置要求

在编写示例代码之前,需要对以下内容有一定的了解:

  1. koa2框架的基础知识
  2. MySQL数据库的基础知识及操作方法
  3. bcrypt加密技术的基础知识

如果对以上内容不熟悉,可以先查阅相关资料进行学习。

步骤1:创建数据库

在MySQL中创建一个名为“users”的数据库,其中包含以下两个表:

user_info表:包含user_id、user_name、password三个字段,用于存储用户的登录信息。

user_profile表:包含user_id、real_name、phone_number两个字段,用于存储用户的个人信息。

示例代码如下:

-- 创建users数据库
CREATE DATABASE IF NOT EXISTS `users` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

-- 使用users数据库
USE `users`;

-- 创建user_info表
CREATE TABLE IF NOT EXISTS `user_info` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(50) NOT NULL,
  `password` varchar(100) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

-- 创建user_profile表
CREATE TABLE IF NOT EXISTS `user_profile` (
  `user_id` int(11) NOT NULL,
  `real_name` varchar(50) DEFAULT NULL,
  `phone_number` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`user_id`),
  CONSTRAINT `user_profile_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user_info` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

步骤2:安装依赖包

在项目根目录下执行以下命令,安装项目所依赖的包:

npm install koa koa-bodyparser koa-router koa-session mysql2 bcrypt

依赖包的介绍如下:

  1. koa:Web框架。
  2. koa-bodyparser:处理请求体的中间件。
  3. koa-router:路由中间件。
  4. koa-session:Session中间件。
  5. mysql2:MySQL的Node.js驱动程序。
  6. bcrypt:加密技术库。

步骤3:建立文件结构

在项目根目录下,建立以下目录和文件:

-- app.js
-- config.js
-- controllers
    -- auth_controller.js
    -- user_controller.js
-- models
    -- user_model.js
-- routes
    -- auth_router.js
    -- user_router.js
-- views
    -- login.pug
    -- register.pug
-- utils
    -- bcrypt_util.js
    -- database_util.js

各文件的作用如下:

  1. app.js:入口文件,用于启动应用并配置相关中间件。
  2. config.js:配置文件,用于存储应用所需的配置项。
  3. controllers:控制器文件夹,用于存储控制器。
  4. models:模型文件夹,用于存储数据模型。
  5. routes:路由文件夹,用于存储路由。
  6. views:视图文件夹,用于存储视图。
  7. utils:工具文件夹,用于存储相关工具函数。

步骤4:配置文件

在config.js文件中,配置以下内容:

module.exports = {
  port: 3000, // 应用监听的端口号
  database: { // 数据库配置
    host: 'localhost', // 数据库连接地址
    port: 3306, // 数据库端口号
    user: 'root', // 数据库用户名
    password: 'root', // 数据库密码
    database: 'users', // 数据库名
    connectionLimit: 10 // 数据库连接池限制
  },
  session: { // Session配置
    key: 'koa2demo', // Session名称
    maxAge: 3600 * 1000 // Session过期时间
  },
  bcrypt: { // bcrypt配置
    saltRounds: 10 // 盐轮数
  }
}

步骤5:工具函数

bcrypt_util.js

在bcrypt_util.js中,编写如下代码:

const bcrypt = require('bcrypt')
const { bcrypt: { saltRounds } } = require('../config')

module.exports = {
  hash: async (password) => {
    const salt = await bcrypt.genSalt(saltRounds)
    const hashedPassword = await bcrypt.hash(password, salt)
    return hashedPassword
  },
  compare: async (password, hashedPassword) => {
    const match = await bcrypt.compare(password, hashedPassword)
    return match
  }
}

该文件中包含hash函数和compare函数,分别用于加密和比对密码。

database_util.js

在database_util.js中,编写如下代码:

const mysql = require('mysql2/promise')
const { database } = require('../config')

const pool = mysql.createPool(database)

module.exports = {
  execute: async (sql, params) => {
    const connection = await pool.getConnection()
    try {
      const [rows] = await connection.execute(sql, params)
      return rows
    } catch (err) {
      throw err
    } finally {
      connection.release()
    }
  }
}

该文件中包含execute函数,用于执行SQL语句并返回查询结果。

步骤6:数据模型

user_model.js

在user_model.js中,编写如下代码:

const { execute } = require('../utils/database_util')

module.exports = {
  create: async ({ userName, password, realName, phoneNumber }) => {
    const sql = 'INSERT INTO `user_info` (`user_name`, `password`) VALUES (?, ?)'
    const hashedPassword = await bcryptUtil.hash(password)
    const params = [userName, hashedPassword]
    const [result] = await execute(sql, params)
    const userId = result.insertId
    const sql2 = 'INSERT INTO `user_profile` (`user_id`, `real_name`, `phone_number`) VALUES (?, ?, ?)';
    const params2 = [userId, realName, phoneNumber]
    await execute(sql2, params2)
    return userId
  },
  findByUserName: async (userName) => {
    const sql = 'SELECT * FROM `user_info` WHERE `user_name` = ?'
    const params = [userName]
    const [rows] = await execute(sql, params)
    return rows[0]
  },
  findById: async (userId) => {
    const sql = 'SELECT * FROM `user_info` WHERE `user_id` = ?'
    const params = [userId]
    const [rows] = await execute(sql, params)
    return rows[0]
  },
  updateById: async (userId, { realName, phoneNumber }) => {
    const sql = 'UPDATE `user_profile` SET `real_name` = ?, `phone_number` = ? WHERE `user_id` = ?'
    const params = [realName, phoneNumber, userId]
    await execute(sql, params)
  }
}

该文件中包含create函数、findByUserName函数、findById函数和updateById函数,分别用于创建用户、根据用户名查找用户、根据用户ID查找用户、根据用户ID更新用户信息。

步骤7:路由

auth_router.js

在auth_router.js中,编写如下代码:

const router = require('koa-router')()
const { register, login, logout } = require('../controllers/auth_controller')

router.post('/api/register', register)
router.post('/api/login', login)
router.post('/api/logout', logout)

module.exports = router.routes()

该文件中定义了三个路由,分别用于用户注册、用户登录和用户注销操作。

user_router.js

在user_router.js中,编写如下代码:

const router = require('koa-router')()
const { getUserInfo, updateUserInfo } = require('../controllers/user_controller')

router.get('/api/user/:id', getUserInfo)
router.put('/api/user/:id', updateUserInfo)

module.exports = router.routes()

该文件中定义了两个路由,分别用于获取用户信息和更新用户信息。

步骤8:控制器

auth_controller.js

在auth_controller.js中,编写如下代码:

const userModel = require('../models/user_model')
const bcryptUtil = require('../utils/bcrypt_util')

module.exports = {
  register: async (ctx) => {
    const { userName, password, realName, phoneNumber } = ctx.request.body
    const user = await userModel.findByUserName(userName)
    if (user) {
      ctx.body = {
        success: false,
        message: '用户名已存在'
      }
    } else {
      const userId = await userModel.create({ userName, password, realName, phoneNumber })
      ctx.session.userId = userId
      ctx.body = {
        success: true,
        message: '注册成功'
      }
    }
  },
  login: async (ctx) => {
    const { userName, password } = ctx.request.body
    const user = await userModel.findByUserName(userName)
    if (user && await bcryptUtil.compare(password, user.password)) {
      ctx.session.userId = user.user_id
      ctx.body = {
        success: true,
        message: '登录成功'
      }
    } else {
      ctx.body = {
        success: false,
        message: '用户名或密码错误'
      }
    }
  },
  logout: async (ctx) => {
    ctx.session = null
    ctx.body = {
      success: true,
      message: '注销成功'
    }
  }
}

该文件中包含register函数、login函数和logout函数,分别用于用户注册、用户登录和用户注销操作。

user_controller.js

在user_controller.js中,编写如下代码:

const userModel = require('../models/user_model')

module.exports = {
  getUserInfo: async (ctx) => {
    const userId = ctx.params.id
    const user = await userModel.findById(userId)
    if (!user) {
      ctx.status = 404
      ctx.body = {
        success: false,
        message: '用户不存在'
      }
    } else {
      const { user_name: userName, ...rest } = user
      const userProfile = { ...rest }
      ctx.body = {
        success: true,
        data: { userName, userProfile }
      }
    }
  },
  updateUserInfo: async (ctx) => {
    const userId = ctx.params.id
    const { realName, phoneNumber } = ctx.request.body
    await userModel.updateById(userId, { realName, phoneNumber })
    ctx.body = {
      success: true,
      message: '更新成功'
    }
  }
}

该文件中包含getUserInfo函数和updateUserInfo函数,分别用于获取用户信息和更新用户信息。

步骤9:视图

login.pug

在login.pug中,编写如下代码:

form(action='/api/login', method='post')
  input(type='text', name='userName', placeholder='用户名')
  input(type='password', name='password', placeholder='密码')
  button(type='submit') 登录

register.pug

在register.pug中,编写如下代码:

form(action='/api/register', method='post')
  input(type='text', name='userName', placeholder='用户名')
  input(type='password', name='password', placeholder='密码')
  input(type='text', name='realName', placeholder='真实姓名')
  input(type='text', name='phoneNumber', placeholder='手机号码')
  button(type='submit') 注册

步骤10:入口文件

在app.js中,编写如下代码:

const Koa = require('koa')
const bodyParser = require('koa-bodyparser')
const session = require('koa-session')
const authRouter = require('./routes/auth_router')
const userRouter = require('./routes/user_router')
const { port, session: { key, maxAge } } = require('./config')

const app = new Koa()

app.keys = [key]
app.use(session({
  key,
  maxAge,
}, app))

app.use(bodyParser())

app.use(authRouter)
app.use(userRouter)

app.listen(port, () => {
  console.log(`Server started at http://127.0.0.1:${port}`)
})

该文件中配置中间件并启动应用。

至此,示例代码编写完成。可以运行项目,在浏览器中访问“http://127.0.0.1:3000/register”和“http://127.0.0.1:3000/login”进行注册和登录。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:koa2实现登录注册功能的示例代码 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • node 可读流与可写流的运用详解

    Node 可读流与可写流的运用详解 概述 在 Node.js 中,读写操作一般来说都会使用流的方式进行。其中可读流提供了一种将数据从 source 输出到 destination 的抽象方式;而可写流则提供了一种将数据写入 destination 的抽象方式。对于数据中间处理过程,我们可以使用管道(piping)的方式链接可读流和可写流。 可读流 核心方法 …

    node js 2023年6月8日
    00
  • 实例详解AngularJS实现无限级联动菜单

    实现无限级联动菜单的步骤 第一步:引入AngularJS 在HTML文件中引入AngularJS库,可以使用CDN或者下载本地文件。例如: <script src="https://cdn.bootcdn.net/ajax/libs/angular.js/1.8.2/angular.min.js"></script&gt…

    node js 2023年6月8日
    00
  • json跨域调用python的方法详解

    前言 在Web开发中,我们经常需要进行跨域调用,其中就有一种情况是JavaScript通过Ajax向Python服务器发送Json格式请求,接收服务器返回的Json格式数据。本文将详细介绍一种基于Flask框架的Python跨域调用处理方法。 步骤一:从Flask导入必要的库 我们首先要导入必要的库。在本例中,我们使用Flask库作为Python的Web框架…

    node js 2023年6月8日
    00
  • 详解关于Vue版本不匹配问题(Vue packages version mismatch)

    详解关于Vue版本不匹配问题(Vue packages version mismatch) 在使用Vue框架过程中,有时会遇到“Vue packages version mismatch”的问题,在控制台会显示类似下面的错误信息: [Vue warn]: You are using the runtime-only build of Vue where th…

    node js 2023年6月8日
    00
  • 浅谈webpack 构建性能优化策略小结

    下面详细讲解“浅谈webpack 构建性能优化策略小结”这篇文章的完整攻略。 一、概述 本文旨在提供一些有关 webpack 构建性能的优化策略,帮助开发者更好地提升构建速度,提高开发效率。本文将从以下四个方面展开: 优化 webpack 配置 优化 loader 和 plugin 优化代码质量和模块规范 使用缓存 二、优化 webpack 配置 减少解析路…

    node js 2023年6月8日
    00
  • nodejs项目windows下开机自启动的方法

    以下是详细讲解Node.js项目Windows下开机自启动的方法攻略: 方案一:使用node-windows模块 安装node-windows模块 npm install -g node-windows 在Node.js项目中引入node-windows模块 const winService = require(‘node-windows’).Service…

    node js 2023年6月8日
    00
  • 详解本地Vue项目请求本地Node.js服务器的配置方法

    下面是详解本地Vue项目请求本地Node.js服务器的配置方法的完整攻略。 环境准备 在开始本地Vue项目请求本地Node.js服务器的配置之前,需要先完成以下环境准备: 安装Node.js,确保版本高于8.0 安装Vue CLI,用于快速搭建Vue项目 步骤一:创建后端服务 首先,需要通过Node.js创建一个本地的后端服务。可以通过Express框架来实…

    node js 2023年6月8日
    00
  • Electron打包React生成桌面应用方法详解

    Electron打包React生成桌面应用方法详解 Electron 可以让你使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序。如果你正在使用 React 开发应用程序,并且想要将其转换为桌面应用程序,那么 Electron 是一个很好的选择。 下面是使用 Electron 打包 React 的步骤: 步骤 1:初始化 React …

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部