前言

这一章写的很没有底气,因为我完全不懂一个正经的后台应用是怎么结构分层的,

所有只能按照我自己的理解去写,即使这样也仅仅只分离出了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()
})
}
})
})
}

utilsindex.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结构分层、配置数据库、接口的更多相关文章

  1. Redis:学习笔记-03

    Redis:学习笔记-03 该部分内容,参考了 bilibili 上讲解 Redis 中,观看数最多的课程 Redis最新超详细版教程通俗易懂,来自 UP主 遇见狂神说 7. Redis配置文件 启动 ...

  2. 机器学习实战(Machine Learning in Action)学习笔记————03.决策树原理、源码解析及测试

    机器学习实战(Machine Learning in Action)学习笔记————03.决策树原理.源码解析及测试 关键字:决策树.python.源码解析.测试作者:米仓山下时间:2018-10-2 ...

  3. OpenCV 学习笔记03 边界框、最小矩形区域和最小闭圆的轮廓

    本节代码使用的opencv-python 4.0.1,numpy 1.15.4 + mkl 使用图片为 Mjolnir_Round_Car_Magnet_300x300.jpg 代码如下: impor ...

  4. OpenCV 学习笔记03 findContours函数

    opencv-python   4.0.1 1 函数释义 词义:发现轮廓! 从二进制图像中查找轮廓(Finds contours in a binary image):轮廓是形状分析和物体检测和识别的 ...

  5. C++ GUI Qt4学习笔记03

    C++ GUI Qt4学习笔记03   qtc++spreadsheet文档工具resources 本章介绍创建Spreadsheet应用程序的主窗口 1.子类化QMainWindow 通过子类化QM ...

  6. ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心

    作者:Grey 原文地址:ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心 前置知识 完成ZooKeeper集群搭建以及熟悉ZooKeeperAPI基本使用 需求 很多程序往 ...

  7. SaToken学习笔记-03

    SaToken学习笔记-03 如果排版有问题,请点击:传送门 核心思想 所谓权限验证,验证的核心就是一个账号是否拥有一个权限码 有,就让你通过.没有?那么禁止访问! 再往底了说,就是每个账号都会拥有一 ...

  8. JavaWeb和WebGIS学习笔记(七)——MapGuide Open Source安装、配置以及MapGuide Maestro发布地图——超详细!目前最保姆级的MapGuide上手指南!

    JavaWeb和WebGIS学习笔记(七)--MapGuide Open Source安装.配置以及MapGuide Maestro发布地图 超详细!目前最保姆级的MapGuide上手指南! 系列链接 ...

  9. 【Unity Shaders】学习笔记——SurfaceShader(二)两个结构体和CG类型

    [Unity Shaders]学习笔记——SurfaceShader(二)两个结构体和CG类型 转载请注明出处:http://www.cnblogs.com/-867259206/p/5596698. ...

随机推荐

  1. 浏览器根对象window之值为字符串的属性

    1. string属性 1.1 origin window.origin使用返回的是当前网页的网址.打开百度首页,并在控制台中输入 window.origin 控制台中会输出"https:/ ...

  2. 通过脚本自动下载Esri会议材料

    在Esri的官网上,可以下载到Esri参加或者举办的各类会议的材料.官方地址为:http://proceedings.esri.com/library/userconf/index.html. 针对某 ...

  3. SVN - Checksum mismatch while updating

    Go to the folder with the file causing problems Execute command svn update --set-depth empty (note: ...

  4. Android GridView显示SD卡的图片

    GridView的XML布局: main.xml: <GridViewxmlns:android="http://schemas.android.com/apk/res/android ...

  5. Rabbitmq安装报错 Windows下安装RabbitMQ报错Error: unable to connect to node rabbit@xxx: nodedown

    1..erlang.cookie文件不一致 如果是Windows 64位系统两个文件都要修改,另外当C:\Users\用户\.erlang.cookie没有修改权限的时候 用上面这个文件覆盖下面两个目 ...

  6. Mysql rpm安装

    总结下mysql rpm安装的方式,与一些错误 环境[root@host2 ~]# uname -aLinux host2 2.6.32-504.3.3.el6.x86_64 #1 SMP Wed D ...

  7. Visual studio 2015已经停止工作无限重启

    今天遇到一个问题,某个文件在撤销的时候vs报错,然后提示到路径 “C:\Users\username\AppData\Roaming\Microsoft\VisualStudio\14.0\***.x ...

  8. TMG 2010 使用脚本来导入URL集和域名集

    作为一个网管,相信有领导叫你限制员工上网的情况,例如只限制员工访问某些网站.在禁止的网站数量少的时候,添加URL集或者域名集是一件很简单的事情,如果禁止的网站数量多达1500个呢?如果再使用ISA S ...

  9. Python错误和异常概念(总)

    转载请标明出处: http://www.cnblogs.com/why168888/p/6435956.html 本文出自:[Edwin博客园] Python错误和异常概念(总) 1. 错误和异常的处 ...

  10. java抽象继承-模板方法

    //模板方法:步骤提前设计好,用的时候只需要改步骤内容 public class TemplateDemo { public static void main(String[] args) { // ...