KOA 入门,简单实现用户注册和登录逻辑
koa
首先来介绍一下什么是 koa。
koa是由Express背后的团队设计的一个新的 Web 框架,旨在成为 Web 应用和 API 的更小、更具表现力和更强大的基础。 通过利用异步函数,koa允许你放弃回调并大大提高错误处理能力。koa的核心中没有捆绑任何中间件,它提供了一套优雅的方法,使编写服务器变得快速而愉快。
基本用法
安转
npm i koa koa-router koa-static koa-views
基本配置
const path = require('path')
const Koa = require('koa')
const app = new Koa()
const Router = require('koa-router')
const static = require('koa-static')
const views = require('koa-views')
// 加载模版引擎
app.use(views(path.join(__dirname, './views'), {
extension: 'ejs' // 模版引擎类型
}))
// 配置静态文件
app.use(static(path.join(__dirname, './static')))
// 设置路由
const router = new Router()
router.get('/', async (ctx) => {
ctx.body = 'hello world'
})
app.use(router.routes(), router.allowedMethods())
app.listen(4000)
按照上面,我们可以继续添加已经封装好的第三方中间件来实现我们所需要的功能。但是下面我们使用一个 koa 的脚手架工具来进行搭建我们的后端服务。
正式开始
下载脚手架和初始化 koa项目
npm install koa-generator -g
koa2 -e koa-cli
cd koa-cli
npm i
koa2 表示用 koa2.x的版本; -e 是指使用 ejs 模版引擎; koa-cli 是项目名称,可以设置自己的 project-name
初始化后,我们用 vscode 打开后应该展示到的目录结构是这样的

这里的目录结构我先不做过多的描述了,接下来直接使用 npm run dev 就可以看到程序跑了起来。在浏览器里访问 localhost:3000,就可以看到欢迎页面了。

好了,本文到此结束(并不是)
接下来我们来连接下数据库,实现一下注册登录等逻辑。
真·正式开始
整理项目目录「也可以不用整理,看个人习惯」
首先我们来整理下项目的目录,首先我们在根目录下创建一个 src 的文件夹,然后将 public文件、routes文件、views文件 以及 app.js 移到 src 目录中,同时 bin 文件中的 www 文件中的对应引用也要做对应的修改。
// var app = require('../app'); // 旧
var app = require('../src/app'); // 新
连接数据库
我们这里选择 mysql 数据库,所以要先在本地安装对应的 mysql 数据库。我这里就默认大家安装好了哈。
在 node 中,连接 mysql 数据库的方法有很多种,其中就有 mysql、mysql2、sequelize
这里的 mysql 是 npm 中的第三模块,并不是指 mysql 数据库
这里我们使用 sequelize
下载安装 sequelize
# 其中 sequelize 中依赖了 mysql2,所以要一并安装 mysql2
npm i sequelize mysql2
然后我们在 src 下创建一个 db 文件夹,用来存放数据库相关。
// src > db > index.js
const Sequelize = require('sequelize')
// 这里创建 sequelize 实例
const sequelize = new Sequelize(
'koa_cli_db', // database
'root', // 数据库用户
'', // 密码
{
host: 'localhost', // 地址
dialect: 'mysql' // 数据库类型
}
)
module.exports = sequelize
这里有一点要注意,
database一定要是真实存在的,所以我们要先在数据库中创建对应的 database。可以使用
CREATE SCHEMA "koa_cli_db"来创建。或者可以下载可视化操作工具来进行操作。例如:Navicat、MySQL Workbench
new Sequelize 中传入数据库相关配置,但是一般我们会将相关配置提取出来。这里我们将相关信息提出。在 src 下创建 config 文件夹,存放相关配置。然后创建 _db.js 文件存放相关配置。
// src > config > _db.js
const SQL_CONFIG = {
database: 'koa_cli_db',
root: 'root',
password: '',
host: 'localhost'
}
module.exports = {
SQL_CONFIG
}
// src > db > index.js
const Sequelize = require('sequelize')
const { SQL_CONFIG } = require('../config/_db')
const sequelize = new Sequelize(SQL_CONFIG.database, SQL_CONFIG.root, SQL_CONFIG.password, {
host: SQL_CONFIG.host,
dialect: 'mysql'
})
完成这一步后,我们来测试是否连接成功数据库,在 db 文件夹下创建 connect.js。
const sequelize = require('./index')
/** sql 链接测试 */
sequelize.authenticate().then(() => {
console.log('连接数据库成功!')
}).catch(err => {
console.log(err)
console.log('连接数据库失败!')
})
然后终端执行 node ./src/db/connect.js 来测试。显示

则说明我们连接数据库成功啦。
建表
连接数据库后,我们就要建表了。sequlize 是一个基于 promise 的 Node.js ORM(对象关系映射)工具。所以对于 sequelize 来说,建表是通过定义对应的对象(我们称模型)来操作的。接下来我们来定义模型,包括字段和关联关系。
首先我们在 db 下创建一个 model 文件夹,用来存放我们定义的模型。在 model 下创建我们第一个模型文件 User.js
// src > db > model > User.js
const sequelize = require('../index')
const { STRING, TEXT } = require('sequelize')
const User = sequelize.define('user', {
// 这里面相当于表的每一列
userName: {
type: STRING, // 数据类型,sequelize 提供的数据类型有:STRING, BOOLEAN, TEXT, INTEGER, DECIMAL等
allowNull: false, // 是否允许为空
comment: '用户名' // 描述
},
password: {
type: STRING,
allowNull: false,
comment: '密码'
},
introduce: {
type: TEXT,
comment: '描述'
},
email: {
type: STRING,
allowNull: false,
comment: '邮箱'
}
})
module.exports = User
如此,我们就创建了 User 模型,接下来我们要用模型创建对应的 mysql中对应的table。
我们这里就直接在 connect.js 文件中直接操作。
// src > db > connect.js
// ... 其他代码
// 引入 User 模型,这里因为只有一个,我就直接引入了。
// 如果是模型很多的情况下,我们可以在 model 中创建 index.js 来做唯一出口,收集所有的 model 并统一导出
require('./model/User')
/** model 同步数据库 */
// 强制同步,会将原先的表格以及数据清空,重新创建新的表格
sequelize.sync({ force: true }).then(() => {
console.log('同步数据库成功')
process.exit()
})
/**
* 标准同步
* sequelize.sync()
* 只有数据库中不存在与模型同名的数据表时才同步
*/
/**
* 动态同步
* sequelize.sync({alter: true})
* 修改同名数据表结构
*/
我们这里使用强制同步,其他同步方式也列举出来了,按需选择
终端执行 node ./src/db/connect.js,然后我们就可以看到

提示成功同步,然后我们就可以在 MySQL Workbench 中看到对应的表。


这里可以看到,User 模型同步后,创建了一个 users 表,里面不仅包括我们设置的属性,还有 id、createdAt、updatedAt 属性。
相关说明:
- User 模型同步表,对应的
表名是sequlize.define()中第一个参数的复数。意思就是创建表的时候会自动加上s。因为先前设置的是user,所以这里表名是users - 创建的表的同时,除了我们定义的属性,
sequelize会自动帮我们设置id,并设置为主键。同时还有createdAt和updatedAt。当然我们也可以手动设置主键,可以通过配置primaryKey: true来实现。
实现注册和登录
表格创建完后,我们接下来就要去添加数据,首先我们实现一下注册用户。
首先我们在 src 目录下创建 service 文件夹,存放模型相关操作
// src > service > user.js
const User = require('../db/model/User')
/**
* 新增用户
*/
async function createUser({ userName, password, email, introduce }) {
const res = await User.create({
userName,
password: password,
email,
introduce,
})
const data = res.dataValues
return data
}
// 测试,测试完后记得删掉或注释
createUser({
userName: 'limoonrise',
password: 'limoonrise',
email: 'limoonrise@163.com',
introduce: '测试测试'
})
module.exports = {
createUser
}
终端运行 node ./src/service/user.js,然后就能在 users 中查看到相关记录。

接着我们先创建一下注册接口。在 routes 文件夹 下创建一个 api 文件夹,这里存放相关接口文件
// src > routes > api > user.js
const router = require('koa-router')()
// 注册接口
router.post('/api/user/register', async(ctx, next) => {
const { userName, password, email, introduce } = ctx.request.body
ctx.body = {
userName,
password,
email,
introduce
}
})
module.exports = router
然后还要去 app.js 中引用
// src > app.js
const userAPI = require('./routes/api/user')
// routes
app.use(userAPI.routes(), userAPI.allowedMethods())
这时可以用 postman 测试下接口,可以看到对应的传值。
接着我们开始写相关逻辑,先在 src 下创建一个 controller 文件夹,存放相关逻辑处理
const { createUser } = require('../service/user')
async function register({ userName, password, email, introduce }) {
// controller 里面可以处理很多,比如在创建用户前判断是否已经存在该用户等
// service
try {
const res = await createUser({
userName,
password,
email,
introduce,
})
return {
code: 0,
data: res
}
} catch (err) {
console.log(err)
return {
code: 1,
message: '创建用户失败'
}
}
}
module.exports = {
register
}
最后,我们回归到 routes 中
router.post('/api/user/register', async(ctx, next) => {
const { userName, password, email, introduce } = ctx.request.body
ctx.body = await register({
userName,
password,
email,
introduce
})
})
这时我们在通过 postman 去测试

这里只是简单实现了注册,现实中还是有很多额外的操作的,比如注册的时候判断注册用户是否已经存在,以及密码注册的时候进行加密处理,而不是直接明文的存进数据库
实现完注册,登录的逻辑就相对比较简单了
首先我们先实现 service
// src > service > user.js
async function findOneUser({ userName, password }) {
const res = await User.findOne({
attributes: ['userName', 'introduce', 'email', 'id'], // 获取哪些属性
where: {
userName,
password
}
})
if (res) return res
return 0
}
module.exports = {
createUser,
findOneUser
}
controller
// src > controller > user.js
const { createUser, findOneUser } = require('../service/user')
async function userLogin({ userName, password }) {
const res = await findOneUser({userName, password})
if (res) {
return {
code: 0,
data: res,
message: '登录成功'
}
} else {
return {
code: 2,
message: '登录失败'
}
}
}
module.exports = {
register,
userLogin
}
最后 routes
// src > routes > api > user.js
// 添加 prefix,记得 注册接口 '/api/user/register' 要改成 ‘/register’
router.prefix('/api/user')
router.post('/login', async(ctx, next) => {
const { userName, password } = ctx.request.body
ctx.body = await userLogin({ userName, password })
})
ok,我们来测试一下

到这里,我们登录也完成了,这里还是只是简单实现了一下。至于其他的操作,比如,我们登录后,要怎么记录用户的登录状态等,有机会再说~

浙公网安备 33010602011771号