下面是针对“koa2实现登录注册功能的示例代码”的完整攻略。
前置要求
在编写示例代码之前,需要对以下内容有一定的了解:
- koa2框架的基础知识
- MySQL数据库的基础知识及操作方法
- 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
依赖包的介绍如下:
- koa:Web框架。
- koa-bodyparser:处理请求体的中间件。
- koa-router:路由中间件。
- koa-session:Session中间件。
- mysql2:MySQL的Node.js驱动程序。
- 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
各文件的作用如下:
- app.js:入口文件,用于启动应用并配置相关中间件。
- config.js:配置文件,用于存储应用所需的配置项。
- controllers:控制器文件夹,用于存储控制器。
- models:模型文件夹,用于存储数据模型。
- routes:路由文件夹,用于存储路由。
- views:视图文件夹,用于存储视图。
- 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技术站