长治房屋出租:Node教程——API接口开发(MangoDB Express)

admin/2020-04-16/ 分类:科技/阅读:

git源码

说明:源码已经所有上传到github,堆栈地址: https://github.com/BM-laoli/Node-api-Design

模块依赖关系图

一、纲领

  • 纲领:
    关于架构,
    1. 首先我们的有一个app.js这个就是根路由起点,用来最初的打入口
      它的功效有:
      1.1 引入模块建立基础的网站服务器,
      1.2 导入bodyPasser,过滤另有处置我们的post请求
      1.3 导入数据库毗邻
      1.4 把路由开放出去

    2. 再来一个main.js它在我的route文件夹下,
      2.1 什么需啊哟再这里做二次阻挡,再举行分配路由,
      2.2 引入两个逻辑处置模块,当请求发来的时刻,若是不是login那么我们就需要验证token,
      2.3 若是接见的是login那么我们需要,发post数据,来处处置验证,然后拿token,
      2.4 若是有token,那么再来接见2.2这里的不是logi的其它路由路径,的校验就通过了,于是乎我们就能分配种种接口了

    3. 详细的解说辅助,工具代码
      3.1 这里有我们在主线逻辑里需要的一些工具
      3.2 中间件Middleware,内里有两个工具,一个是天生token的一个校验token的
      3.3 在3.2中的功效 需要依赖model下的一个util下的jwt工具天生token天生的依据是两个密钥对
      3.4 我们另有两个工具,content 建立数据库的链接,create初始化数据另有开发数据操作工具

二、展示 接口 API文档

1.1 登录

请求地址 请求方式
/main/login POST
参数名称 是否必选 参数说明
email 邮箱
password 密码
{ "status": 200, "msg": "上岸乐成", "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoiNWU5MTIwMTViOWI0NmYzZmE4Y2MzMjUzIiwiZXhwIjoxNTg2OTUyMzk1LCJpYXQiOjE1ODY5NTA1OTV9.IsprCaQ_gZRh0BzS8SnAd0iJ27BOpOEb-ZGn0bTlwHVPTiYPK50wiEOL_0aAYINfNT_Mfvb726l3CpiHG9lsJ45m4eqhPeJz9TbAeQj8-ST3CAkYLrD0fhgRG9YiQ5kjVpygdR8NZEWEUV7ux-moyYe7wCoVzN9mbvAkFF3IYG0" } 

1.2 拿着token举行测试

请求地址 请求方式
/main/text get
参数名称 是否必选 参数说明
token 需要附上你的token。在请求头中
该接口不需要通报参数
{ "status": 200, "msg": "上岸乐成" } 

注重:以上就是Node写接口的最基础的内容。可以在这个内容上扩展更多的接口

二、 app.js模块的详解

app.js

//引入模块,建立简朴服务器 const express = require('express'); //引入路径处置模块 const path = require('path'); //引入注重使用第三方模块处置post const bodyPaser = require('body-parser') // 引入数据库毗邻 不需要返回值 require('./model/content') //建立服务器 const app = express(); /*//初始化数据库,注重reque的时刻 会自动执行引入的js文件 require('./model/create') */ //前往小心这个要放在所有的use前面,剖析我们的post请求数据 app.use(bodyPaser.urlencoded({ extended: false })); //处置静态资源路径 const DataPath = path.join(__dirname, 'public'); //这个我们后面是有用的,用来操作媒体数据,最主要的就是这个路径另有这个静态资源工具 const StaticUtils = express.static(path.join(__dirname, 'public')); //拿到路由操作工具 const main = require('./route/mian/main'); //开放接口路径 //阻挡请求最先匹配路由 app.use('/dataPath', (req, res) => { res.status(200).send(JSON.stringify({ 'dataPath': DataPath })) }) app.use(StaticUtils); app.use('/main', main) //监听端口 app.listen(3000) console.log('服务器开启'); 

三、 main.js二次路由阻挡模块

main.js

const express = require('express') //营业逻辑 const guard = require('../../Middleware/loginGuard') const loginPash = require('../../Middleware/loginPash') //建立路由工具 const admin = express.Router() //验证token admin.use(loginPash) //登录路由处置 admin.post('/login', guard) //首先要验证,然后才是放行到对应的路由接口内里取 admin.get('/text', require('./API/home/index')) module.exports = admin; 
  • 携带的一个简朴的测试模块(后续可以模仿这样的模式,写更多的API接口功效模块)
    home/index.js
module.exports = async(req, res) => { res.send({ status: 200, msg: '上岸乐成', }); } 

四、 辅助工具(重点!!!)

  • 数据库毗邻,设计另有初始化建立模块
    model/content.js && model/create.js
 const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/blog') .then(() => { console.log('数据库毗邻乐成'); }) .catch((erro) => { console.log(erro); }) 
 const mongoose = require('mongoose'); const bcrypt = require('bcrypt') /*使用MongDB数据库,设计数据第一步(代码角度剖析) 1.设定规则,Schema组织器,Schema的组织函数就是规则,注重规则是一系列工具 2.建立数据 */ const userSchema = new mongoose.Schema({ username: { type: String, required: true, min: 2, max: 10 }, email: { type: String, //注重 我们的邮箱凭证是用户登录的令牌,我们需要指定他为唯一的 unique: true, //这个时刻,在插入的时刻若是有重复的就给你抱一个错误 }, password: { type: String, required: true, }, role: { //需要说明一下,这个地方角色,我们硬性规定,超级管理员是admin普通用户是normal,为什么不用01?由于这里string了 type: String, required: true }, state: { //我们使用O1状态来设计这个数据字段,默认值是0。0是启用状态 type: Number, default: 0 } }) //使用规则建立聚集, //一定要注重,我们的User就是代表了我现在最user数据聚集,后期的增删改查我们都需要用到这个器械,所有我们露出出去给路由营业使用 const User = mongoose.model('User', userSchema) //我们再来温习一下,如何用同步的方式获取异步的api效果?使用async 另有awit就可以 async function createUser() { const salt = await bcrypt.genSalt(10) const pass = await bcrypt.hash('123456', salt) const user = await User.create({ username: 'lli', email: '18376621755@163.com', password: pass, role: 'admin', state: 0, }) } // createUser() /* // 初始化用户,注重我们的create返回的是一个promies User.create({ username: 'bmlaoli', email: '861795660@qq.com', password: '123456', role: 'admin', state: 0, }) .then(() => { console.log('用户建立乐成'); }) .catch((error) => { console.log('用户建立失败'); })*/ //注重啊,es6中若是键值对的名字是一样的就可以省略值。由于我们后期还会做更多的数据聚集,于是乎我这里需要露出一个工具出去 module.exports = { User } 
  • 另一个主要的工具模块,用来建立token 凭据就是文件夹下的两个密钥对文件
    jwt.js
 /* *形貌:以下是jwt工具,天生用于接见验证的token */ // 引入模块依赖 const fs = require('fs'); const path = require('path'); const jwt = require('jsonwebtoken'); // 建立 token 类 class Jwt { constructor(data) { this.data = data; } //天生token generateToken() { let data = this.data; let created = Math.floor(Date.now() / 1000); let cert = fs.readFileSync(path.join(__dirname, '../../pem/private_key.pem')); //私钥 可以自己天生,注重这里要使用 密钥对,请求百度下载,两对密钥对 let token = jwt.sign({ data, exp: created 60 * 30, }, cert, { algorithm: 'RS256' }); return token; } // 校验token verifyToken() { let token = this.data; let cert = fs.readFileSync(path.join(__dirname, '../../pem/public_key.pem')); //公钥 可以自己天生 let res; try { let result = jwt.verify(token, cert, { algorithms: ['RS256'] }) || {}; let { exp = 0 } = result, current = Math.floor(Date.now() / 1000); if (current <= exp) { res = result.data || {}; } } catch (e) { res = 'err'; } return res; } } module.exports = Jwt; 
  • 接下里是两个详细的token校验功效模块
    我把它们都放到了middleware文件夹下
    loginGuard.js && loginPash.js
const JwtUtil = require('../model/util/jwt') const { User } = require('../model/create') const bcrypt = require('bcrypt') const guard = async(req, res, next) => { //注重使用第三方模块处置post //进图详细的营业逻辑,解构出来我们需要的器械 const { email, password, _id } = req.body; //注重啊,由于我们的中间件处置的请求于是乎我们的req身上就有这个处置的所有数据了,这个之前有说过 console.log(req.body); if (email.trim().length == 0 || password.trim().length == 0) { res.status(400).send( JSON.stringify({ message: '邮箱或密码错误' }) ) //注重send自动把状态码设置成了200,以是你需要改一下 return } //若是用户存在就先找到这个用户额信息,注重这里的这个异步await let user = await User.findOne({ email }); //这里的user就是指向当前查询出来的数据文档工具 if (user) { //比对操作,第一个参数是一个明文密码,第二个参数我们查询出来的加密密码 ,方式返回一个Boolean值,对比乐成就是true,异步api可以直接加await const isValid = await bcrypt.compare(password, user.password) if (isValid) { //用户校验乐成,添加tooken // 上岸乐成,添加token验证 let _id = user._id.toString(); // 将用户id传入并天生token let jwt = new JwtUtil(_id); let token = jwt.generateToken(); // 将 token 返回给客户端 res.send({ status: 200, msg: '上岸乐成', token: token }); //校验乐成就 next() } else { res.status(400).send( JSON.stringify({ message: '邮箱或密码错误' }) ) } } else { res.status(400).send( JSON.stringify({ message: '邮箱或密码错误' }) ) } } module.exports = guard 

loginPash.js

 const JwtUtil = require('../model/util/jwt') //验证token const loginPash = function(req, res, next) { // 我这里知识把上岸和注册请求去掉了,其他的多有请求都需要举行token校验 if (req.url != '/login?') { let token = req.headers.token; let jwt = new JwtUtil(token); let result = jwt.verifyToken(); // 若是磨练通过就next,否则就返回上岸信息不正确 if (result == 'err') { console.log(result); console.log(req.url); res.send({ status: 403, msg: '登录已过期,请重新登录' }); // res.render('login.html'); } else { next(); } } else { next(); } }; module.exports = loginPash; 

五、 最后我们梳理一下,这些模块之间的关系

实在这套接口下来,我对照菜鸡,用了两天的事情之余的时间,由于我没怎么接触接口的设计,对于后台的一些设计模式另有理念不是稀奇懂,走了许多弯路,以上的是我写了三次条记,长达2000多行子,频频的修改,才成型,希望大佬高抬贵手指点迷津,也希望,这篇入门的文档,能给你带来收获,接下里,我就用这里的模子,开发更多的接口。敬请期待。

  • 各个模块的引用关系,用例图

,

Sunbet

Sunbet www.monetary-reproduction.com Sunbet仅需短短几秒,全天24小时无休止无限制免费注册,sunbet欢迎您的光临!

TAG:
阅读:
广告 330*360
广告 330*360
Sunbet_进入申博sunbet官网
微信二维码扫一扫
关注微信公众号
新闻自媒体 Copyright © 2002-2019 Sunbet 版权所有
二维码
意见反馈 二维码