前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用 koa2 搭建中间件

使用 koa2 搭建中间件

作者头像
4O4
发布2022-04-25 16:51:03
1.2K0
发布2022-04-25 16:51:03
举报
文章被收录于专栏:404404

使用 koa2 搭建中间件

安装依赖

代码语言:javascript
复制
{
    "crypto-js": "^3.1.9-1",                   // 加密
    "koa": "^2.8.1",                           // ...
    "koa-bodyparser": "^4.2.1",                // 解析数据
    "koa-router": "^7.4.0",                    // ...
    "koa-sslify": "^4.0.3",                    // 开启ssl
    "koa2-cors": "^2.0.6",                     // 跨域
    "mongodb": "^3.3.1",                       // ...
    "mongoose": "^5.6.11",                     // 更优雅的操作mongodb
    "request": "^2.88.0",                      // ...
    "request-promise": "^4.2.2",               // 发起请求
    "xml2js": "^0.4.23"                        // 微信支付格式化
 }

项目结构

代码语言:javascript
复制
|-- ssl/ SSL证书目录
		|-- api.domain.com.crt
    |-- api.domain.com.key

|-- src/ 源代码目录
    |-- controllers/ 控制器
        |-- order.js 订单
        |-- user.js 用户
        |-- ...    
        
    |-- db/ 数据库相关
        |-- connection.js 数据库连接文件
        
    |-- router/ koa路由
        |-- index.js 路由
       
    |-- schemas/ mongoose文档架构
        |-- order.js 订单
        |-- user.js 用户
        |-- ...  
          
   	|-- utils/ 工具类
        |-- encrypt.js 加密
        |-- roles.js 权限
        |-- ... 
    
    |-- app.js 入口文件
    |-- config.js 配置文件
    |-- ...

配置https

在根目录新建 ssl 文件夹,放入证书文件

在 app.js 中引入 koa-sslify 和 fs

代码语言:javascript
复制
const sslify = require('koa-sslify').default;
const fs = require('fs');

配置证书目录

代码语言:javascript
复制
const httpsOption = {
  key: fs.readFileSync("../ssl/api.domain.com.key"),
  cert: fs.readFileSync("../ssl/api.domain.com.crt")
}

将应用层中间件绑定到应用程序对象的实例

代码语言:javascript
复制
app.use(sslify());

启动一个端口为3000 的 https 的服务

代码语言:javascript
复制
https.createServer(httpsOption, app.callback()).listen(3000, (err) => {
  if (err) {
    console.log('server error', err);
  } else {
    console.log('uni-server is running in port: 3000');
  }
});

浏览器访问 https://localhost:3000

提示不安全是因为 localhost 与证书域名 api.domain.com 不符

配置数据库

在 config.js 中配置连接字符串

代码语言:javascript
复制
module.exports = {
  // 数据库链接字符串
  mongoUrl: 'mongodb://db:pwd@api.domain.com:27017/db',
  // JWT
  jwtKey: 'zephyr-jwt-secret-key',
  hwtHead: {
    "typ": "JWT",
    "alg": "HS256"
  },
  jwtPayload: {
    "iss": "",                          // 签发人
    "sub": "",                          // jwt所面向的用户
    "aud": "",                          // 接收jwt的一方
    "exp": "",                          // jwt的过期时间
    "nbf": "",                          // 定义在什么时间之前,该jwt都是不可用的
    "iat": "",                          // jwt的签发时间
    "jti": "",                          // jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击
    "name": "",                         // 自定义
    "auth": ""                          // 自定义
  }
}

在 connection.js 中连接数据库

代码语言:javascript
复制
const mongoose = require('mongoose');

const DB_URL = require("../config").mongoUrl;

mongoose.connect(DB_URL, { useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false })
  .then(() => console.log("we are connected"))
  .catch(error => console.log(error));

文档架构

User 架构

代码语言:javascript
复制
const mongoose = require('mongoose');

const User = new mongoose.Schema({
  openid: String,
  sessionKey: String,
  info: {
    nickName: String,
    gender: Number,
    city: String,
    province: String,
    country: String,
    avatarUrl: String
  },
  createAt: Number,
  updateAt: Number
})

module.exports = mongoose.model('User', User);

控制器

User 控制器

代码语言:javascript
复制
require('../db/connection');
const request = require('request-promise');
const User = require('../schemas/user');
const appid = require('../config').appid;
const secret = require('../config').secret;

class UserController {
  async getOpenId(ctx, next) {
    const code = ctx.request.query.code || null;
    const info = JSON.parse(ctx.request.query.info) || null;

    if (code) {
      try {
        const res = JSON.parse(await request({
          uri: `https://api.weixin.qq.com/sns/jscode2session?appid=${appid}&secret=${secret}&js_code=${code}&grant_type=authorization_code`
        }))

        if (res) {
          const userItem = new User({
            openId: res.openid || '',
            sessionKey: res.session_key || '',
            info: info,
            createAt: '',
            updateAt: ''
          });

          const doc = await User.find({
            openid: res.openid
          });

          // 如果openid不存在
          if (!doc) {
            userItem.createAt = Math.round(new Date() / 1000);
            userItem.updateAt = 0;
            const _save = await userItem.save();
            ctx.body = {
              code: 1,
              msg: 'ok',
              uid: res.openid,
              result: _save
            }
          } else {
            const filter = { openId: res.openid };
            const update = { sessionKey: res.session_key, info: info, updateAt: Math.round(new Date() / 1000) };

            let doc = await User.findOneAndUpdate(filter, update, (res) => {
              return res;
            });
            
            ctx.body = {
              code: 1,
              msg: 'ok',
              result: res.openid
            }
          }
        }
      } catch (err) {
        ctx.body = {
          code: 0,
          msg: err.message || 'Server error'
        }
      }
    } else {
      ctx.body = {
        code: 0,
        msg: err.message || 'Need code'
      }
    }

  }
}

module.exports = new UserController();

路由

代码语言:javascript
复制
// 部分路由
const router = require('koa-router')();
const userctrl = require('../controllers/user');
const bannerctrl = require('../controllers/banner');
const goodctrl = require('../controllers/good');
const cartctrl = require('../controllers/cart');
const sortctrl = require('../controllers/sort');
const addrctrl = require('../controllers/addr');
const appraisalctrl = require('../controllers/appraisal');
const orderctrl = require('../controllers/order');
const smsctrl = require('../controllers/sms');

router
  // 用户模块
  .get('/user/openid', userctrl.getOpenId)

  // 订单模块
  .get('/pay/order', orderctrl.getOrders)
  .post('/pay/order', orderctrl.addOrder)
  .put('/pay/order', orderctrl.editOrder)
  .delete('/pay/order', orderctrl.deleteOrder)

  // 支付模块
  .post('/pay/unifiedorder', orderctrl.unifiedorOrder)
  .post('/pay/callback', orderctrl.callBack)

  // 商品模块
  .get('/source/good', goodctrl.getGood) // 通过 query?id=10001 查询单个商品,否则查询全部
  .post('/source/good', goodctrl.addGood)
  .put('/source/good', goodctrl.editGood)
  .delete('/source/good', goodctrl.deleteGood)

module.exports = router;

访问

浏览器访问 https://localhost:3000/source/good?id=10001 查询 id 为 10001 的商品

DONE !

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-03-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用 koa2 搭建中间件
    • 安装依赖
      • 项目结构
        • 配置https
          • 配置数据库
            • 文档架构
              • 控制器
                • 路由
                  • 访问
                  相关产品与服务
                  数据库
                  云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档