用egg.js来写一个api管理系统(一)
Egg.js是一个基于Node.js的企业级开发框架,非常适合构建API服务。
安装egg.js
首先,您需要安装Node.js和npm(Node Package Manager)。然后,您可以通过运行以下命令来安装Egg.js:
npm i egg --save
然后,您可以使用以下命令创建一个新的Egg.js项目:
npx egg-init <project-name>
接下来,您可以通过修改config/config.default.js文件来配置您的应用程序。
最后,您可以在您的Egg.js项目中编写控制器和路由,以实现您的API管理系统。
给系统加一个token验证
您可以使用JWT(JSON Web Token)来为您的API管理系统添加令牌验证。
首先,您可以在您的Egg.js项目中安装jsonwebtoken库:
npm install jsonwebtoken --save
然后,您可以在您的控制器中编写代码来生成和验证JWT令牌:
const jwt = require('jsonwebtoken');// 生成JWT令牌
const token = jwt.sign({ data: 'foobar' }, 'secret', { expiresIn: '1h' });// 验证JWT令牌
jwt.verify(token, 'secret', (err, decoded) => {if (err) {console.error(err);} else {console.log(decoded);}
});
您可以在请求头中包含JWT令牌,并在您的路由中检查令牌是否有效。如果令牌无效,则可以向用户返回401错误代码。
此外,您还可以使用Egg.js中间件来自动验证令牌,以简化代码:
// 创建令牌验证中间件
const jwtMiddleware = (req, res, next) => {const token = req.headers.authorization;if (!token) {return res.status(401).send({ error: '令牌丢失' });}try {const decoded = jwt.verify(token, 'secret');req.user = decoded;next();} catch (err) {return res.status(401).send({ error: '令牌无效' });}
};// 应用令牌验证中间件
app.use(jwtMiddleware);
请注意,以上代码仅作为示例,请不要在生产环境中使用硬编码的密钥。请使用随机生成的密钥或通过其他方式(如环境变量)安全存储密钥。
除此之外,您可以使用其他方法,如比对令牌中的用户ID与数据库中的用户记录,来进一步验证令牌的有效性。
您还可以使用Egg.js的插件机制,来简化令牌验证的流程。例如,您可以安装egg-jwt插件,它提供了一个简单的方法来处理JWT令牌验证。
最后,请注意,令牌验证是安全的关键组成部分,请确保您的代码遵循最佳安全实践,以防止令牌被滥用或窃取。
使用OAuth2.0进行令牌验证
以下是一个简单的示例,展示了如何使用Egg.js和OAuth2.0进行令牌验证:
npm install egg-oauth2-server
在config.default.js文件中,配置OAuth2.0服务器:
exports.oauth2server = {grantType: ['password', 'refresh_token'],
};
创建一个中间件,用于检查请求中是否包含令牌,并验证令牌的有效性:
// app/middleware/oauth.js
const OAuth = require('egg-oauth2-server');module.exports = (options, app) => {const oauth = new OAuth(options, app);return async function oauthMiddleware(ctx, next) {try {await oauth.authenticate();await next();} catch (err) {ctx.status = 401;ctx.body = {error: err.message,};}};
};
在所有需要认证的路由上使用该中间件:
// app/router.js
module.exports = app => {const { router, controller } = app;const oauthMiddleware = app.middleware.oauth();router.get('/api/user', oauthMiddleware, controller.user.info);
};
这是一个简单的实现,您可以根据您的需求进行调整。如果您想了解更多关于OAuth2.0的信息,请参阅OAuth2.0规范。
使用JWT进行令牌验证
使用JWT进行令牌验证的具体代码也可能因您所使用的实现而异。然而,以下是一个简单的示例,展示了如何使用Egg.js和JWT进行令牌验证:
npm install jsonwebtoken
创建一个秘密,用于加密和解密令牌:
// app/config/config.default.js
exports.jwt = {secret: 'your_secret_key',
};
创建一个中间件,用于检查请求中是否包含令牌,并验证令牌的有效性:
// app/middleware/authentication.js
const jwt = require('jsonwebtoken');module.exports = (options, app) => {return async function authenticationMiddleware(ctx, next) {const token = ctx.header.authorization;if (!token) {ctx.status = 401;ctx.body = {error: 'No token provided in request headers',};return;}try {const decoded = jwt.verify(token, app.config.jwt.secret);ctx.state.user = decoded;await next();} catch (err) {ctx.status = 401;ctx.body = {error: 'Invalid token',};}};
};
在所有需要认证的路由上使用该中间件:
// app/router.js
module.exports = app => {const { router, controller } = app;const authenticationMiddleware = app.middleware.authentication();router.get('/api/user', authenticationMiddleware, controller.user.info);
};
给每个用户一个唯一的API密钥
// app/middleware/authenticate.js
module.exports = () => {return async function authenticate(ctx, next) {const apiKey = ctx.header.apikey;// 在数据库中查找用户const user = await ctx.model.User.findOne({ apiKey });if (!user) {ctx.status = 401;ctx.body = { message: 'Unauthorized' };return;}// 将用户信息存储在上下文中,以便在其他地方使用ctx.state.user = user;await next();};
};// app/router.js
module.exports = app => {const { router, middleware } = app;const authenticate = middleware.authenticate();router.get('/api/v1/resources', authenticate, ctx => {// 访问 API 资源});
};
这个代码示例使用一个中间件函数来验证请求中的API密钥。如果密钥是有效的,则该中间件函数将用户信息存储在上下文中,并将控制传递给下一个中间件函数或路由处理程序。如果密钥是无效的,则中间件函数将返回401 Unauthorized响应。
限制用户的访问次数
您可以通过记录并限制每个用户的API请求数来限制用户的访问次数。
可以在存储用户数据的数据库中添加一个字段,用于记录每个用户在特定时间段内对API的访问次数。每当用户对API进行请求时,您可以将其请求数加1。如果用户的请求数超过了限制,则拒绝其请求并向其返回适当的错误消息。
代码实现的示例如下:
// app/middleware/api_key_auth.js
const jwt = require('jsonwebtoken');
const { secret } = require('config').security;module.exports = (options, app) => {return async function apiKeyAuth(ctx, next) {// 获取请求头中的 API Keyconst apiKey = ctx.headers['x-api-key'];// 验证 API Key 是否存在if (!apiKey) {ctx.status = 401;ctx.body = { error: 'Unauthorized' };return;}// 验证 API Key 是否正确try {const decoded = jwt.verify(apiKey, secret);const user = await app.models.User.findOne({ apiKey: decoded.apiKey });// 验证 API Key 对应的用户是否存在if (!user) {ctx.status = 401;ctx.body = { error: 'Unauthorized' };return;}// 验证用户访问次数是否超限if (user.requestCount >= user.requestLimit) {ctx.status = 429;ctx.body = { error: 'Too Many Requests' };return;}// 将用户的信息挂载到 ctx 上,方便在后续的处理中使用ctx.user = user;// 将用户的访问次数加 1await app.models.User.updateOne({ apiKey: decoded.apiKey }, { $inc: { requestCount: 1 } });// 继续执行后续的请求处理await next();} catch (err) {ctx.status = 401;ctx.body = { error: 'Unauthorized' };}};
};// config/config.default.js
module.exports = {security: {secret: 'your secret'}
};// app/router.js
module.exports = app => {const { router, controller } = app;router.get('/', controller.home.index);router.get('/secret', app.middleware.apiKeyAuth(), controller.home.secret);
};
请注意,在这个示例中,用户数据是写死在代码中的,在生产环境中,您应该将用户数据存储在数据库中以便更好地管理。
相关文章:
用egg.js来写一个api管理系统(一)
Egg.js是一个基于Node.js的企业级开发框架,非常适合构建API服务。 安装egg.js 首先,您需要安装Node.js和npm(Node Package Manager)。然后,您可以通过运行以下命令来安装Egg.js: npm i egg --save然后&a…...

企业数字化转型和升级:架构设计方法与实践
目录 企业架构整体结构 企业架构的驱动力 企业架构的基本概念 企业架构的发展 企业架构框架理论 主流企业架构框架之对比 企业架构整体结构 图例:企业架构整体结构 企业架构整体结构从战略层、规划层、落地层这三层来分别对应企业架构中 业务、架构和实施的各种重要…...

【LeetCode】环形链表 II [M](链表)
142. 环形链表 II - 力扣(LeetCode) 一、题目 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链…...
Unity之如何实现一个VR任务(剧情)系统
一.前言 最近再做一个VR项目,里面有大量的剧情和VR操作任务。 比如: 1.张三说了什么话,干了什么事,然后,李四又说了什么,做了什么动画,完了之后,场景中某个物体高亮,让我们触摸或者射线点击(pc的话鼠标点击)和其发生交互。 2.我们使用VR手柄或者鼠标与场景中的一个…...

k8s核心概念与kubectl命令行工具的使用
k8s官方文档Kubernetes 文档 | Kubernetes作用:kubernetes用于容器化应用程序的部署,扩展和管理。目标:是让部署容器化应用简单高效。Kubernetes集群架构与组件 Master组件 kube-apiserverkubernetes API,集群的统一入口ÿ…...

【零基础入门前端系列】—无序列表、有序列表、定义列表(四)
一、HTML无序列表 无序列表是一个项目的列表,此列项目使用粗体圆点(典型的小黑圆圈)进行标记。 无序列表使用 <ul> 标签 <ul> <li>Coffee</li> <li>Milk</li> </ul>嵌套结构: <…...

为什么重写equals还要重写hashcode方法
目录equals方法hashCode方法为什么要一起重写?总结面试如何回答重写 equals 时为什么一定要重写 hashCode?要想了解这个问题的根本原因,我们还得先从这两个方法开始说起。 以下是关于hashcode的一些规定: 两个对象相等࿰…...

电子技术——电流镜负载的差分放大器
电子技术——电流镜负载的差分放大器 目前我们学习的差分放大器都是使用的是差分输出的方式,即在两个漏极之间获取电压。差分输出主要有以下优势: 降低了共模信号的增益,提高了共模抑制比。降低了输入偏移电压。提升了差分输入的增益。 由于…...
go面试题
1.json包在使用的时候,结构体里的变量不加tag能不能正常转成json里的字段? 如果变量首字母小写,则为private。无论如何不能转,因为取不到反射信息。如果变量首字母大写,则为public。 不加tag,可以正常转为j…...

攻防世界-Confusion1
题目 访问题目场景 某天,Bob说:PHP是最好的语言,但是Alice不赞同。所以Alice编写了这个网站证明。在她还没有写完的时候,我发现其存在问题。(请不要使用扫描器) 然后结合图片我们知道,这个网址是python写的࿰…...

机器学习实战--梯度下降法进行波士顿房价预测
前言: Hello大家好,我是Dream。 今天来学习一下如何使用机器学习梯度下降法进行波士顿房价预测,这是简单的一个demo,主要展示的是一些小小的思路~ 本文目录:一、波士顿房价预测1.全部的数据可视化2.地理数据可视化3.房…...

黑马】后台管理-项目优化和上线
一。项目优化优化1,加载进度条显示安装一个运行依赖,nprogress然后导包,调用对象展示和隐藏在main中基于拦截器实现展示进度条和隐藏进度条的效果如果触发请求拦截器,证明发起请求,希望展示进度条,如果触发…...
Web 框架 Flask 快速入门(三)数据库-MySQL
课程地址:Python Web 框架 Flask 快速入门 文章目录数据库1、数据库的安装与配置2、数据库的简单使用——增删改1. 定义数据模型2. 增删改3、 关系引用——表的关联4、查询——通过SQLAlchemy扩展5、其他1. 数据模型的实现(疑惑)6、Bug记录1.…...

牛客网Python篇数据分析习题(六)
1.某公司计划举办一场运动会,现有运动会项目数据集items.csv。 包含以下字段: item_id:项目编号; item_name:项目名称; location:比赛场地。 有员工报名情况数据集signup.csv。包含以下字段: employee_id&a…...

Ansible的安装及部署
目录 一、Ansible对于企业运维的重大意义 二、Ansible的安装 三、构建Ansible清单 1.直接书写受管主机名或ip,每行一个 2.设定受管主机的组[组名称] 四、Ansible配置文件参数详解 1、配置文件的分类与优先级 2.配置新用户的Ansible配置 3.生成免密认证 本章…...

链表题目总结 -- 递归
目录一. 递归反转整个链表1. 思路简述2. 代码3. 总结二. 反转链表前 N 个节点1. 思路简述2. 代码3. 总结三、反转链表的一部分1. 思路简述2. 代码3.总结四、从节点M开始反转后面的链表1. 思路简述2. 代码3.总结一. 递归反转整个链表 题目链接:https://leetcode.cn/…...

重写-linux内存管理-伙伴分配器(一)
文章目录一、伙伴系统的结构二、初始化三、分配内存3.1 prepare_alloc_pages3.2 get_page_from_freelist3.2.1 zone_watermark_fast3.2.2 zone_watermark_ok3.2.3 rmqueue3.2.3.1 rmqueue_pcplist3.2.3.2 __rmqueue3.2.3.2.1 __rmqueue_smallest3.2.3.2.2 __rmqueue_fallback3.…...

为什么要用springboot进行开发呢?
文章目录前言1、那么Springboot是怎么实现自动配置的1.1 启动类1.2 SpringBootApplication1.3 Configuration1.4 ComponentScan1.5 EnableAutoConfiguration1.6 两个重要注解1.7 AutoConfigurationPackage注解1.8 Import(AutoConfigurationImportSelector.class)注解1.9自动配置…...
设备树信息解析相关函数
一。可以通过三种不同的方式解析设备树节点: 1.根据设备树节点的名字解析设备树节点 struct device_node *of_find_node_by_name(struct device_node *from, const char *name); 参数: from:当前节点父节点首地址 name:设备树节点名字 …...
LeetCode-1124. 表现良好的最长时间段【哈希表,前缀和,单调栈】
LeetCode-1124. 表现良好的最长时间段【哈希表,前缀和,单调栈】题目描述:解题思路一:查字典。cur是当前的前缀和(劳累与不劳累天数之差),向前遍历。有两种情况。情况一,若cur大于0则是[0,i]的劳累与不劳累天…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...