koa2学习笔记03 - 给koa2配置session ——koa2结构分层、配置数据库、接口
前言
这一章写的很没有底气,因为我完全不懂一个正经的后台应用是怎么结构分层的,
所有只能按照我自己的理解去写,即使这样也仅仅只分离出了controller层,
至于所谓的service层,dao层,完全不懂该怎么分离出来。
所以这一章仅供参考。如果有人能指点一下,不胜感激。
正文
数据库是采用的mysql,所以需要在本机安装一个mysql。
具体安装这里不多说了,请移步 菜鸟教程。
置于MySQL图形化管理工具推荐使用 navicat 或者 heidisql
1 安装依赖
npm install koa-session-minimal koa-mysql-session mysql --save
2 配置数据库和session
config 目录下新建 config.js 放置配置文件。
const database = {
host: '127.0.0.1', // 数据库地址,本机默认127.0.0.1
port: 3306, // 数据库默认端口
database: 'koa2db', // 数据库名字
user: 'root', // 数据库默认用户名
password: 'XXXX' // 你设置的数据库密码
}
module.exports = {
database: database
}
改造根目录下的 app.js
// 配置session
app.use(session({
key: 'USER_SID',
store: new MysqlStore(mysqlConfig),
cookie: {
maxAge: 1000 * 60 * 60 * 24, // cookie有效时长
overwrite: false
}
}))
具体如图:

然后运行项目,看是否在数据库中自动创建了一个 _mysql_session_store 的表。 如果成功说明配置成功。

3 配置接口,分离controller
在目录 router 中新建 api 目录,放置各模块接口。再新建api.js作为 api的入口文件。
我们可以在里面加入一些测试接口,捕获不存在的接口、输出不存在的错误接口方便排查。
api.js
const router = require('koa-router')();
const user = require('./api/user.js');
router.prefix('/api'); // 统一定义接口前缀都为api, 之后写的所有接口都在api下。
user(router);
/* 测试接口 */
router.get('/', function (ctx, next) {
ctx.body = {
code: 0,
data: null,
msg: "接口请求成功",
request: ctx.originalUrl
}
})
/* 404 */
router.all('/*', function (ctx, next) {
ctx.body = {
code: 1001,
ctx: ctx,
data: null,
msg: "接口不存在",
request: ctx.originalUrl
}
})
module.exports = router
// router.get() ==> 仅仅get请求可以访问到接口
// router.post() ==> 仅仅post请求可以访问到接口
// router.all() ==> 所有请求都可以访问到接口
定义好了接口的入口文件,我们先在
app.js引入

引入之后接下来配置接口的详细信息,在
routers中 新建api目录, 并在其中新建user.js
/**
* 用户相关接口
*/
const user = require("../../controller/user.js")
module.exports = function(router) {
router.all('/user/login', user.userLogin)
router.all('/user/isLogin', user.isLogin)
}
根目录下新建目录
controller,controller下新建user.js, 此处暂不考虑密码明文传输安全性问题。
const { responseFormatter, getParams } = require("../utils/index.js") // 格式化输出方法、获取参数方法
const { logHandle } = require("../utils/logs.js") // 上一章记录操作日志的方法
const handleDB = require("../utils/handleDb.js") // 操作数据库方法
// 用户登录接口
async function userLogin(ctx, next) {
var params = getParams(ctx.request)
try {
let sql = "select * from user where username=? and password=?"
let data = await handleDB(sql, [params.username, params.password]);
// 记录登录日志
logHandle({
title: '用户登录',
sql,
params,
data
});
if (data.length) {
// 存入session信息(最终会存在数据库中)
ctx.session = {
isLogin: true,
userId: data[0].userId,
userName: data[0].username,
nickName: data[0].nickname
}
ctx.body = responseFormatter(0, '登录成功!');
} else {
ctx.body = responseFormatter(201);
}
} catch (err) {
ctx.body = responseFormatter(103, err);
}
}
// 检测用户是否登录接口
async function isLogin(ctx, next) {
if (ctx.session && ctx.session.isLogin) {
ctx.body = responseFormatter(0, {
nickName: ctx.session.nickName
});
} else {
ctx.body = responseFormatter(202);
}
}
module.exports = {
isLogin,
userLogin
}
utils目录下的index.js
/**
* @name responseFormatter 格式化输出响应结果
* @params { @Number 状态码, @Object 返回数据}
* @return { @Object }
* @author HoChine.
*/
const errorCode = require("../config/errorCode.js")
exports.responseFormatter = function (code, data) {
return {
code: code,
msg: errorCode[code],
data: data || null
}
}
/**
* @name getParams 获取url参数
* @params { @String url}
* @return { @Object }
* @author HoChine.
*/
let getUrlParams = function (url) {
let paramsList = {};
if (!url) {
console.log("url 为必填项");
return paramsList;
}
let paramsStr = url.split("?")[1];
let params = paramsStr ? paramsStr.split("&") : [];
params.forEach(function (item) {
let temp = item.split("=");
temp[0] ? paramsList[temp[0]] = temp[1] : '';
})
return paramsList;
}
exports.getUrlParams = getUrlParams
/**
* @name getParams 根据请求方式不同获取参数
* @params { @Object ctx.request}
* @return { @Object }
* @author HoChine.
*/
exports.getParams = function (request) {
if (request.method === "GET") {
return getUrlParams(request.url)
}else{
return request.body
}
}
utils目录下的handleDb.js。 database为上面的数据库配置文件
onst mysql = require('mysql')
const { database } = require('../config/config');
const pool = mysql.createPool(database);
module.exports = function(sql, values) {
return new Promise((resolve, reject) => {
pool.getConnection(function(err, connection) {
if (err) {
reject(err)
} else {
connection.query(sql, values, (err, rows) => {
if (err) {
reject(err)
} else {
resolve(rows)
}
connection.release()
})
}
})
})
}
utils中index.js所引入的errorCode.js
/* 错误码1-2位按服务端业务模块区分
* 01. 接口相关 (参数不全等,参数有误)
* 02. user相关
* 03. blog相关
*/
/* 错误码3-4位按具体错误情况排列
* 01.
* 02.
*/
module.exports = {
0: 'success',
101: '缺少必须参数!',
102: '参数有误!',
103: '接口异常',
201: '用户不存在!',
202: '用户未登录或已过期!',
203: '用户名或密码错误,请重试!',
220: '抱歉,您没有权限!',
9999: '未知错误!'
};
最后配置一下数据库 随意新增一条数据。

至此,接口、session、数据库配置基本上配置好了。
4 前台页面验证
view目录下的 index.html (是我不知道在哪抄来的一个登录模块样式)
<!DOCTYPE HTML>
<html>
<head>
<title>Home</title>
<link href="/stylesheets/style.css" rel="stylesheet" />
</head>
<body>
<div class="login" style="display:none">
<h2>商家登录 </h2>
<div class="login-top">
<h1>登录</h1>
<form>
<input type="text" id="username" placeholder="用户名" value="admin">
<input type="password" id="password" placeholder="******" value="admin">
</form>
<div class="forgot">
<a href="#">忘记密码?</a>
<input type="button" id="login" value="登录">
</div>
</div>
<div class="login-bottom">
<h3>400-000-0000</h3>
</div>
</div>
<div class="logined" style="display:none"></div>
</body>
<script src="http://libs.baidu.com/jquery/2.1.1/jquery.min.js"></script>
<script src="/javascripts/index.js"></script>
</html>
public中的stylesheets样式文件,具体可以github上复制,放这里太占篇幅 。 style.css点这里
public中的javascripts登录逻辑随便写写,不要深究写的SB不SB,只是测试接口用。
$(function() {
isLogin()
function isLogin() {
$.get("http://localhost:3000/api/user/isLogin", function(res) {
console.log(res);
if (res.code) {
$(".login").show();
login()
} else {
$(".logined").show().text("hello, " + res.data.nickName)
}
})
}
function login() {
$("#login").on("click", function() {
var username = $("#username").val();
var password = $("#password").val();
if (username && password) {
$.post("http://localhost:3000/api/user/login", {
username: username,
password: password
}, function(res) {
console.log(res);
if(!res.code){
alert(res.data);
location.reload();
}
})
} else {
alert("用户名或密码为空")
}
})
}
})
作者 HoChine
2019 年 04月 16日
GitHub地址:https://github.com/HoChine/Koa2-demo/tree/03
koa2学习笔记03 - 给koa2配置session ——koa2结构分层、配置数据库、接口的更多相关文章
- Redis:学习笔记-03
Redis:学习笔记-03 该部分内容,参考了 bilibili 上讲解 Redis 中,观看数最多的课程 Redis最新超详细版教程通俗易懂,来自 UP主 遇见狂神说 7. Redis配置文件 启动 ...
- 机器学习实战(Machine Learning in Action)学习笔记————03.决策树原理、源码解析及测试
机器学习实战(Machine Learning in Action)学习笔记————03.决策树原理.源码解析及测试 关键字:决策树.python.源码解析.测试作者:米仓山下时间:2018-10-2 ...
- OpenCV 学习笔记03 边界框、最小矩形区域和最小闭圆的轮廓
本节代码使用的opencv-python 4.0.1,numpy 1.15.4 + mkl 使用图片为 Mjolnir_Round_Car_Magnet_300x300.jpg 代码如下: impor ...
- OpenCV 学习笔记03 findContours函数
opencv-python 4.0.1 1 函数释义 词义:发现轮廓! 从二进制图像中查找轮廓(Finds contours in a binary image):轮廓是形状分析和物体检测和识别的 ...
- C++ GUI Qt4学习笔记03
C++ GUI Qt4学习笔记03 qtc++spreadsheet文档工具resources 本章介绍创建Spreadsheet应用程序的主窗口 1.子类化QMainWindow 通过子类化QM ...
- ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心
作者:Grey 原文地址:ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心 前置知识 完成ZooKeeper集群搭建以及熟悉ZooKeeperAPI基本使用 需求 很多程序往 ...
- SaToken学习笔记-03
SaToken学习笔记-03 如果排版有问题,请点击:传送门 核心思想 所谓权限验证,验证的核心就是一个账号是否拥有一个权限码 有,就让你通过.没有?那么禁止访问! 再往底了说,就是每个账号都会拥有一 ...
- JavaWeb和WebGIS学习笔记(七)——MapGuide Open Source安装、配置以及MapGuide Maestro发布地图——超详细!目前最保姆级的MapGuide上手指南!
JavaWeb和WebGIS学习笔记(七)--MapGuide Open Source安装.配置以及MapGuide Maestro发布地图 超详细!目前最保姆级的MapGuide上手指南! 系列链接 ...
- 【Unity Shaders】学习笔记——SurfaceShader(二)两个结构体和CG类型
[Unity Shaders]学习笔记——SurfaceShader(二)两个结构体和CG类型 转载请注明出处:http://www.cnblogs.com/-867259206/p/5596698. ...
随机推荐
- 英文版win10更新以后, 中文软件变成乱码
原因是非Unicode程序的语言设置失效了 在区域设置里把当前系统区域设置改成"英语(美国)", 重启电脑后再改回"中文(简体, 中国)", 再重启就好了.
- 基于PMBOK的项目管理知识体系
- 三层构架 和 MVC 是什么?
作者:肖继潮链接:https://www.zhihu.com/question/24291079/answer/27339010著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 企 ...
- N点虚拟主机管理系统如何使用?
有朋友问起N点虚拟主机管理系统怎么用呢?下面大概整理下他的使用方法,咱们来看看吧. 在讲如何使用N点虚拟主机管理系统之前,我们先来了解一下N点虚拟主机管理系统的介绍. N ...
- centos 卸载python和yum之后的解决办法
网上看到有同学yum不能使用的消息,出现了下面的结果 无赖的使用了网上的很多方法,还是不行. 于是我卸载了python和yum,觉得自己重新安装python和yum. 步骤1:卸载python rpm ...
- [翻译] GSProgressView
GSProgressView 本人极不推荐使用drawRect的方式来绘制下载进度条,无论机器的性能怎么高,使用drawRect用于绘制图形都是低效的. A cute little circular ...
- Java实例---flappy-bird实例[最终版]
代码分析 解析版: Java实例---flappy-bird实例解析 完整版: TestBirdFly.java package testfly; import java.awt.Color; imp ...
- 骑士周游问题跳马问题C#实现(附带WPF工程代码)
骑士周游问题,也叫跳马问题. 问题描述: 将马随机放在国际象棋的8×8棋盘的某个方格中,马按走棋规则进行移动.要求每个方格只进入一次,走遍棋盘上全部64个方格. 代码要求: 1,可以任意选定马在棋盘上 ...
- Mac Sublime Text3快捷键
下载地址http://www.sublimetext.com/3 一.安装Package Control 按Ctrl + ` 调出console,粘贴下列安装代码到底部命令行并回车: import u ...
- Nginx Web服务器配置
Nginx是一个轻量级高性能的web服务器,它是为快速响应大量静态文件请求和高效利用系统资源而设计的.与apache使用面向进程或线程的方式处理请求不同,nginx使用异步事件驱动模型在连接高并发的情 ...
