前言

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

所有只能按照我自己的理解去写,即使这样也仅仅只分离出了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. H5禁止手机自带键盘弹出

    一个功能中用到这个, 调用软键盘,  不想弹出手机默认的输入法 网上找了个 http://blog.csdn.net/qq_24147051/article/details/52958610 处理方式 ...

  2. 数据分析之scipy常用方法(五)

    1 Scipy简介 Scipy依赖于Numpy Scipy提供了真正的矩阵 Scipy包含的功能:最优化.线性代数.积分.插值.拟合.特殊函数.快速傅里叶变换.信号处理.图像处理.常微分方程求解器等 ...

  3. 打通版微社区(2):服务器部署MySql数据库 For DZ3.2

    写在前面:单独写部署MySql原因是,我这边的应用数据库都是独立存在的,数据与应用分别部署在不同的服务器.另外我也没有实际部署MySql的经验,特意写一篇日志,张记性.安装MySql参考了http:/ ...

  4. matlab中的knn函数

    knn 最邻近分类 Class = knnclassify(test_data,train_data,train_label, k, distance, rule) k:选择最邻近的数量 distan ...

  5. Asp.Net MVC Identity 2.2.1 使用技巧(七)

    创建角色管理相关视图 1.添加视图 打开RolesAdminController.cs   将鼠标移动到public ActionResult Index()上  右键>添加视图   系统会弹出 ...

  6. December 10th 2016 Week 50th Saturday

    Storms make trees take deeper roots. 风暴使树木深深扎根. Sometimes, you may feel frustrated for failing to wi ...

  7. January 08 2017 Week 2nd Sunday

    Believe not all that you see nor half what you hear. 眼见的不能全信,耳闻的也不能半信. What you hear, what you see, ...

  8. HDU4578 线段树(区间更新 + 多种操作)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578  , 线段树的区间更新 + 多种操作,好题. 虽然是比较裸的线段树,但是比较麻烦,并且有很多细节 ...

  9. HTTP协议图--HTTP 协议基础

    1.通过请求和响应的交换达成通信 应用 HTTP 协议时,必定是一端担任客户端角色,另一端担任服务器端角色.仅从一条通信线路来说,服务器端和客服端的角色是确定的.HTTP 协议规定,请求从客户端发出, ...

  10. elasticsearch 相关

    1.对elsasticsearch index的解释,What exactly is an index in Elasticsearch ? basic definition An index is  ...