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

简介: 前端如何快速为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们,一起来试试吧。



相关文章
|
存储 前端开发 安全
前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
本文全面解析前端三种数据存储方式:Cookie、LocalStorage与SessionStorage。涵盖其定义、使用方法、生命周期、优缺点及典型应用场景,帮助开发者根据登录状态、用户偏好、会话控制等需求,选择合适的存储方案,提升Web应用的性能与安全性。(238字)
1205 0
《仿盒马》app开发技术分享-- 确认订单页(数据展示)(29)
上一节我们实现了地址的添加,那么有了地址之后我们接下来的重点就可以放到订单生成上了,我们在购物车页面,点击结算会跳转到一个 订单确认页面,在这个页面我们需要有地址选择、加购列表展示、价格计算、优惠计算、商品数量展示等信息。
322 3
|
11月前
|
数据采集 弹性计算 运维
打造您的专属赛事神经中枢 | 专业比分网/APP开发服务
我们为体育俱乐部、媒体、社区等打造专属实时比分平台,覆盖全球赛事,支持多终端访问,提供毫秒级更新、精准数据与个性化推送,助力高效观赛体验。
|
9月前
|
存储 前端开发 安全
实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
381 5
|
前端开发 安全 开发工具
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
1084 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
764 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
存储 消息中间件 前端开发
PHP后端与uni-app前端协同的校园圈子系统:校园社交场景的跨端开发实践
校园圈子系统校园论坛小程序采用uni-app前端框架,支持多端运行,结合PHP后端(如ThinkPHP/Laravel),实现用户认证、社交关系管理、动态发布与实时聊天功能。前端通过组件化开发和uni.request与后端交互,后端提供RESTful API处理业务逻辑并存储数据于MySQL。同时引入Redis缓存热点数据,RabbitMQ处理异步任务,优化系统性能。核心功能包括JWT身份验证、好友系统、WebSocket实时聊天及活动管理,确保高效稳定的用户体验。
724 4
PHP后端与uni-app前端协同的校园圈子系统:校园社交场景的跨端开发实践
|
BI 开发工具 开发者
App全渠道统计方案:如何用一个工具整合所有获客渠道数据?
还在为地推、社群、广告等不同获客渠道的数据分散而烦恼吗?本文将教您如何用一个工具整合所有渠道数据,实现精准的渠道归因与效果分析。
446 0
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
1013 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
前端开发 Cloud Native Java
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现

热门文章

最新文章

  • 1
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
    1205
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    537
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    418
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    414
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    525
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    706
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    1296
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    300
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    1079
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    491