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

下面是针对“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日

相关文章

  • 用Nodejs实现在终端中炒股的实现

    下面是使用Node.js实现在终端中炒股的完整攻略: 简介 本篇攻略将使用Node.js实现在终端中炒股的功能。具体实现思路是爬取股票数据和终端显示。通过爬取API接口的方式来获得股票数据。使用Query Table库在终端中显示表格,并使用Chalk库为表格着色。 实现步骤 构建查询函数 首先需要构建一个查询股票信息的函数,该函数将会调用一个API接口来获…

    node js 2023年6月8日
    00
  • WebSocket+node.js创建即时通信的Web聊天服务器

    我将为你讲解 “WebSocket+node.js创建即时通信的Web聊天服务器” 的完整攻略。 1. 什么是WebSocket? WebSocket是一种基于TCP连接的全双工通信协议,可以实现客户端与服务器之间的双向实时通信,不需要手动轮询。 2. WebSocket的使用环境 在使用WebSocket之前,需要确认以下两点: 1.客户端浏览器是否支持W…

    node js 2023年6月8日
    00
  • Nodejs使用archiver-zip-encrypted库加密压缩文件时报错(解决方案)

    当我们在使用Node.js编写代码时,有时我们需要用到压缩和加密文件的功能。在这种情况下,我们可以使用archiver-zip-encrypted库来实现这一目的。但是,在使用该库时可能会出现一些问题,如报错等。 以下是解决“Nodejs使用archiver-zip-encrypted库加密压缩文件时报错”的完整攻略: 问题描述 在使用archiver-zi…

    node js 2023年6月8日
    00
  • node.js中的console.error方法使用说明

    下面是关于“node.js中console.error方法的使用说明”的攻略。 console.error方法的介绍 在node.js中,console模块提供了一组简单的调试工具,包括console.log、console.error、console.warn和console.info等方法。这些方法支持格式化输出、多参数输出、输出堆栈跟踪等特性。在这些方…

    node js 2023年6月8日
    00
  • IOS之WebSocket框架Starscream案例详解

    IOS之WebSocket框架Starscream案例详解 简介 Starscream是一种WebSocket协议的Swift框架,可以用于iOS、macOS、watchOS和tvOS平台上的客户端应用程序。它支持RFC 6455协议以及多个子协议,并且提供了完整的SSLError错误处理。 安装 你可以使用CocoaPods来安装Starscream。在你…

    node js 2023年6月8日
    00
  • Node中使用ES6语法的基础教程

    下面就是“Node中使用ES6语法的基础教程”的完整攻略: 目录 背景 ES6语法的基础了解 let和const 箭头函数 模板字符串 解构赋值 扩展运算符 类与继承 模块化 Node中使用ES6语法的实践 使用Babel ES6模块化在Node中的使用 小结 背景 ES6(又称ES2015)是ECMAScript标准的第6个版本,由于其新增了许多方便的语法…

    node js 2023年6月8日
    00
  • nodejs acl的用户权限管理详解

    Node.js ACL的用户权限管理详解 概述 在Node.js应用中,用户权限管理是非常重要的一个功能,其中一个常用的实现方式是使用 node_acl 模块。 node_acl 是一个封装了 redis 的简单的权限控制列表模块,在许多 Node.js 应用程序中都被广泛使用。 ACL 模块的核心思想是,在用户请求时,检查这个用户是否有权限执行特定的操作,…

    node js 2023年6月8日
    00
  • IDEA中配置运行node.js的完整过程

    下面是在IDEA中配置运行node.js的完整过程的详细攻略。 步骤一:安装Node.js插件 在开始配置Node.js的运行环境之前,我们需要先在IDEA中安装Node.js插件。具体操作步骤如下: 打开IDEA,进入“Settings”(Windows下位于File菜单下,Mac下位于IntelliJ IDEA菜单下)。 找到“Plugins”选项,点击…

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