当前位置: 首页 > news >正文

用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的企业级开发框架&#xff0c;非常适合构建API服务。 安装egg.js 首先&#xff0c;您需要安装Node.js和npm&#xff08;Node Package Manager&#xff09;。然后&#xff0c;您可以通过运行以下命令来安装Egg.js&#xff1a; npm i egg --save然后&a…...

企业数字化转型和升级:架构设计方法与实践

目录 企业架构整体结构 企业架构的驱动力 企业架构的基本概念 企业架构的发展 企业架构框架理论 主流企业架构框架之对比 企业架构整体结构 图例&#xff1a;企业架构整体结构 企业架构整体结构从战略层、规划层、落地层这三层来分别对应企业架构中 业务、架构和实施的各种重要…...

【LeetCode】环形链表 II [M](链表)

142. 环形链表 II - 力扣&#xff08;LeetCode&#xff09; 一、题目 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链…...

Unity之如何实现一个VR任务(剧情)系统

一.前言 最近再做一个VR项目,里面有大量的剧情和VR操作任务。 比如: 1.张三说了什么话,干了什么事,然后,李四又说了什么,做了什么动画,完了之后,场景中某个物体高亮,让我们触摸或者射线点击(pc的话鼠标点击)和其发生交互。 2.我们使用VR手柄或者鼠标与场景中的一个…...

k8s核心概念与kubectl命令行工具的使用

k8s官方文档Kubernetes 文档 | Kubernetes作用&#xff1a;kubernetes用于容器化应用程序的部署&#xff0c;扩展和管理。目标&#xff1a;是让部署容器化应用简单高效。Kubernetes集群架构与组件 Master组件 kube-apiserverkubernetes API&#xff0c;集群的统一入口&#xff…...

【零基础入门前端系列】—无序列表、有序列表、定义列表(四)

一、HTML无序列表 无序列表是一个项目的列表&#xff0c;此列项目使用粗体圆点&#xff08;典型的小黑圆圈&#xff09;进行标记。 无序列表使用 <ul> 标签 <ul> <li>Coffee</li> <li>Milk</li> </ul>嵌套结构&#xff1a; <…...

为什么重写equals还要重写hashcode方法

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

电子技术——电流镜负载的差分放大器

电子技术——电流镜负载的差分放大器 目前我们学习的差分放大器都是使用的是差分输出的方式&#xff0c;即在两个漏极之间获取电压。差分输出主要有以下优势&#xff1a; 降低了共模信号的增益&#xff0c;提高了共模抑制比。降低了输入偏移电压。提升了差分输入的增益。 由于…...

go面试题

1.json包在使用的时候&#xff0c;结构体里的变量不加tag能不能正常转成json里的字段&#xff1f; 如果变量首字母小写&#xff0c;则为private。无论如何不能转&#xff0c;因为取不到反射信息。如果变量首字母大写&#xff0c;则为public。 不加tag&#xff0c;可以正常转为j…...

攻防世界-Confusion1

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

机器学习实战--梯度下降法进行波士顿房价预测

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

黑马】后台管理-项目优化和上线

一。项目优化优化1&#xff0c;加载进度条显示安装一个运行依赖&#xff0c;nprogress然后导包&#xff0c;调用对象展示和隐藏在main中基于拦截器实现展示进度条和隐藏进度条的效果如果触发请求拦截器&#xff0c;证明发起请求&#xff0c;希望展示进度条&#xff0c;如果触发…...

Web 框架 Flask 快速入门(三)数据库-MySQL

课程地址&#xff1a;Python Web 框架 Flask 快速入门 文章目录数据库1、数据库的安装与配置2、数据库的简单使用——增删改1. 定义数据模型2. 增删改3、 关系引用——表的关联4、查询——通过SQLAlchemy扩展5、其他1. 数据模型的实现&#xff08;疑惑&#xff09;6、Bug记录1.…...

牛客网Python篇数据分析习题(六)

1.某公司计划举办一场运动会&#xff0c;现有运动会项目数据集items.csv。 包含以下字段&#xff1a; item_id&#xff1a;项目编号&#xff1b; item_name:项目名称&#xff1b; location:比赛场地。 有员工报名情况数据集signup.csv。包含以下字段&#xff1a; employee_id&a…...

Ansible的安装及部署

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

链表题目总结 -- 递归

目录一. 递归反转整个链表1. 思路简述2. 代码3. 总结二. 反转链表前 N 个节点1. 思路简述2. 代码3. 总结三、反转链表的一部分1. 思路简述2. 代码3.总结四、从节点M开始反转后面的链表1. 思路简述2. 代码3.总结一. 递归反转整个链表 题目链接&#xff1a;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自动配置…...

设备树信息解析相关函数

一。可以通过三种不同的方式解析设备树节点&#xff1a; 1.根据设备树节点的名字解析设备树节点 struct device_node *of_find_node_by_name(struct device_node *from, const char *name); 参数&#xff1a; from&#xff1a;当前节点父节点首地址 name:设备树节点名字 …...

LeetCode-1124. 表现良好的最长时间段【哈希表,前缀和,单调栈】

LeetCode-1124. 表现良好的最长时间段【哈希表&#xff0c;前缀和&#xff0c;单调栈】题目描述&#xff1a;解题思路一&#xff1a;查字典。cur是当前的前缀和(劳累与不劳累天数之差)&#xff0c;向前遍历。有两种情况。情况一&#xff0c;若cur大于0则是[0,i]的劳累与不劳累天…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...