前端如何快速为App搭建数据服务

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: 前端如何快速为App搭建数据服务

前言:


作为一个Coder虽然主要在做前端方面的开发,但是为了可以更好的协作开发,还是很有必要学习后端的一些知识,最起码你可以了解到什么东西是真的实现不了😏。


技术栈:


  • 基础项目:eggjs
  • 时间处理:dayjs
  • 数据加密:md5
  • UID生成:uuid
  • 鉴权处理:jsonwebtoken
  • 参数校验:egg-validate
  • 跨域限制:egg-cors
  • 数据存储:egg-mongoose


选择Eggjs原因:


Egg.js 为企业级框架和应用而生,我们希望由 Egg.js 孕育出更多上层框架,帮助开发团队和开发人员降低开发和维护成本。”

我们可以通过eggjs提供的脚手架生成一套完整的项目结构,这对于我们快速学习将是非常有必要的,接下来我们就一起了解一下eggjs基础项目的的结构,对于初次使用我们就只关注如下的目录即可。1.png


了解第一个Controller:


  • Controller意为控制器,我们主要的后端逻辑处理的地方(当然过多的通用逻辑应该抽取到Service层),我们通过this指针结构到ctx上下文对象,并将要返回的内容赋值给body,接着我们在router.js中增加router.get('/', controller.home.index);就可以启动服务后在浏览器访问IP:PORD得到3号标题的内容了。
'use strict';
const Controller = require('egg').Controller;
class HomeController extends Controller {
  async index() {
    const { ctx } = this;
    ctx.body = '<h3>欢迎使用可追溯查询数据提供服务</h3>';
  }
}
module.exports = HomeController;
复制代码


接下来试着实现用户的基本操作:


  • 这次我们先定义好如下三个路由,分别对应用户的登录,信息获取,登出三种操作。
router.post('/dev-api/user/login', controller.user.login);
router.get('/dev-api/user/info', controller.user.info);
router.post('/dev-api/user/logout', controller.user.logout);
复制代码


  • 因为会涉及到数据存储,鉴权,跨域,我们将先配置好中间件来避免后续的麻烦,具体的包自行安装就好。
// server\config\plugin.js
exports.mongoose = {
  enable: true,
  package: 'egg-mongoose',
};
exports.validate = {
  enable: true,
  package: 'egg-validate',
};
exports.cors = {
  enable: true,
  package: 'egg-cors',
};
复制代码
// server\config\config.default.js
module.exports = appInfo => {
  ...
  config.cors = {
    origin: '*', // 表示允许的源
    allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH', // 表示允许的http请求方式
  };
  return {
    ...
    security: {
      csrf: {
        enable: false,
      },
    },
    bodyParser: {
      jsonLimit: '5mb', // 允许传输内容的大小限制
      formLimit: '5mb',
    },
    mongoose: {
      client: {
        url: 'mongodb://<这块有时间单独说,各位先百度也行>',
        options: {
          autoReconnect: true,
          reconnectTries: Number.MAX_VALUE,
          bufferMaxEntries: 0,
        },
      },
    },
  };
};
复制代码


  • MongoDB对应的用户和Token模型定义:
module.exports = app => {
  const mongoose = app.mongoose;
  const Schema = mongoose.Schema;
  const UserSchema = new Schema({
    username: { type: String, required: true },
    password: { type: String, required: true },
    roles: { type: Array, required: true },
    introduction: { type: String, required: true },
    avatar: { type: String, required: true },
    name: { type: String, required: true },
  }, { timestamps: true });
  return mongoose.model('User', UserSchema);
};
module.exports = app => {
  const mongoose = app.mongoose;
  const Schema = mongoose.Schema;
  const TokenSchema = new Schema({
    token: { type: String, required: true },
  }, { timestamps: true });
  return mongoose.model('Token', TokenSchema);
};
复制代码


  • 还准备了一个公共的BaseController,将统一处理接口的返回格式:
'use strict';
const Controller = require('egg').Controller;
class BaseController extends Controller {
  success(data) {
    this.ctx.body = {
      code: 20000,
      data,
    };
  }
  message(message) {
    this.ctx.body = {
      code: 20000,
      message,
    };
  }
  error(message, code = -1, errors = {}) {
    this.ctx.body = {
      code,
      message,
      errors,
    };
  }
}
module.exports = BaseController;
复制代码


  • 总算要开始我们的用户Controller的编写了,继承自BaseController,并导入了加密、鉴权,也定义了操作校验的对象loginUserRule
'use strict';
const BaseController = require('./base');
const KEY = require('../key');
const jwt = require('jsonwebtoken');
const md5 = require('md5');
const loginUserRule = {
  username: { type: 'string' },
  password: { type: 'string' },
};
class UserController extends BaseController {
  async login() {
    const { ctx } = this;
  }
  async info() {
    const { ctx } = this;
  }
  async logout() {
    const { ctx } = this;
  }
}
module.exports = UserController;
复制代码


  • 参数校验统一处理参照如下:
const { ctx } = this;
try {
  ctx.validate(loginUserRule);
} catch (e) {
  return this.error('参数校验失败', -1, e.errors);
}
复制代码


  • 登录接口编写
  • 首先通过request对象的body属性得到请求中的用户名和密码;
  • 通过用户名在MongoDB中查找用户,成功找到说明用户名正常;
  • 通过将密码进行md5加密与存储的密码比对,成功则说明密码正常;
  • 使用jwt将用户名写入并生成token,存储到MongoDB中;
  • token成功存储后成功响应前端接口数据。


const { username, password } = ctx.request.body;
const ret = await ctx.model.User.findOne({ username });
if (ret.password && ret.password === md5(password)) {
  const token = jwt.sign({ username }, KEY.secretOrPrivateKey);
  const tokenRet = await ctx.model.Token.create({
    token,
  });
  if (tokenRet._id) {
    this.success({ token });
  }
} else {
  this.error('用户名或密码错误');
}
复制代码


  • 用户信息获取接口编写
  • 获取用户信息的接口将只需要传递token即可;
  • 我们通过将接收到的token进行Mongo查询,成功查询说明Token正常;
  • 通过验证token正确性得到被写入的用户名;
  • 我们在通过用户名查询Mongo中对应的详细信息,成功查询后相应前端接口数据。
const token = ctx.request.header['x-token'];
const ret = await ctx.model.Token.findOne({ token });
if (ret) {
  const { username } = jwt.verify(token, KEY.secretOrPrivateKey);
  const userRet = await ctx.model.User.findOne({ username });
  if (userRet) {
    this.success(userRet);
  }
}
复制代码


  • 登出接口编写
  • 同样通过获取token并查询,成功查询说明token正常;
  • 这时候我们只需要删除token,成功响应前端接口数据即可。
const token = ctx.request.header['x-token'];
const ret = await ctx.model.Token.findOne({ token });
if (ret) {
  const tokenRet = await ctx.model.Token.deleteOne({ token });
  if (tokenRet && tokenRet.ok === 1) {
    this.success('success');
  }
} else {
  this.error('服务器暂无在线记录');
}
复制代码

至此我们就已经实现了一个最简单的App中用户的基本操作(登录,信息获取,登出)的功能,当然在实际的业务中将更为复杂。


总结:


这个流程下来,其实涉及的知识点还不少,比如说MongoDB的存取操作,JWT的生成验证,还有统一个数据结构应用的必要等,没有为自己App提供过服务的Coder们,一起来试试吧。



相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
27天前
|
存储 监控 安全
前端框架的数据驱动方式如何保证数据的安全性?
总之,前端框架的数据驱动方式需要综合运用多种手段来保证数据的安全性。从传输、存储、访问控制到防范攻击等各个方面进行全面考虑和实施,以确保用户数据的安全可靠。同时,不断加强安全管理和技术创新,以应对不断变化的安全挑战。
105 60
|
11天前
|
人工智能 自然语言处理 前端开发
从0开始打造一款APP:前端+搭建本机服务,定制暖冬卫衣先到先得
通义灵码携手科技博主@玺哥超carry 打造全网第一个完整的、面向普通人的自然语言编程教程。完全使用 AI,再配合简单易懂的方法,只要你会打字,就能真正做出一个完整的应用。
8883 20
|
2天前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
21 3
|
15天前
|
人工智能 自然语言处理 芯片
上千人挑战,用通义灵码从 0 开始打造一款 App 爆火 | 第二课:搭建本机服务
通义灵码携手科技博主@玺哥超carry 打造全网第一个完整的、面向普通人的自然语言编程教程。完全使用 AI,再配合简单易懂的方法,只要你会打字,就能真正做出一个完整的应用。
1088 9
|
2月前
|
JSON 前端开发 Java
震惊!图文并茂——Java后端如何响应不同格式的数据给前端(带源码)
文章介绍了Java后端如何使用Spring Boot框架响应不同格式的数据给前端,包括返回静态页面、数据、HTML代码片段、JSON对象、设置状态码和响应的Header。
161 1
震惊!图文并茂——Java后端如何响应不同格式的数据给前端(带源码)
|
2月前
|
存储 前端开发 JavaScript
前端的全栈之路Meteor篇(四):RPC方法注册及调用-更轻量的服务接口提供方式
RPC机制通过前后端的`callAsync`方法实现了高效的数据交互。后端通过`Meteor.methods()`注册方法,支持异步操作;前端使用`callAsync`调用后端方法,代码更简洁、易读。本文详细介绍了Methods注册机制、异步支持及最佳实践。
|
2月前
|
监控 JavaScript 前端开发
前端的混合之路Meteor篇(六):发布订阅示例代码及如何将Meteor的响应数据映射到vue3的reactive系统
本文介绍了 Meteor 3.0 中的发布-订阅模型,详细讲解了如何在服务器端通过 `Meteor.publish` 发布数据,包括简单发布和自定义发布。客户端则通过 `Meteor.subscribe` 订阅数据,并使用 MiniMongo 实现实时数据同步。此外,还展示了如何在 Vue 3 中将 MiniMongo 的 `cursor` 转化为响应式数组,实现数据的自动更新。
|
2月前
|
JSON 分布式计算 前端开发
前端的全栈之路Meteor篇(七):轻量的NoSql分布式数据协议同步协议DDP深度剖析
本文深入探讨了DDP(Distributed Data Protocol)协议,这是一种在Meteor框架中广泛使用的发布/订阅协议,支持实时数据同步。文章详细介绍了DDP的主要特点、消息类型、协议流程及其在Meteor中的应用,包括实时数据同步、用户界面响应、分布式计算、多客户端协作和离线支持等。通过学习DDP,开发者可以构建响应迅速、适应性强的现代Web应用。
|
2月前
|
JavaScript 前端开发 Python
django接收前端vue传输的formData图片数据
django接收前端vue传输的formData图片数据
62 4
|
2月前
|
JSON API 网络安全
App数据的爬取
App数据的爬取
42 3