群控系统服务端开发模式-应用开发-业务架构逻辑开发第一轮测试
整个系统的第一个层次已经开发完毕,已经有简单的中控,登录、退出、延迟登录时长、黑名单、数据层封装、验证层封装、RSA加解密、Redis等功能,还缺获取个人、角色按钮权限、角色菜单权限功能。角色按钮权限以及角色菜单权限等明后天开发,今天先开发个人信息接口以便测试使用。
一、个人信息接口开发
1、添加路由
在根目录下route文件夹中的app.php文件中加入以下代码:
Route::post('member/personal_data','permission.Member/personalData');
2、代码开发
在根目录下app文件夹下的controller文件夹中创建文件夹并命名为permission,然后在permission文件夹中创建控制器并命名为Member,然后在Member文件中继承Base总控制后并创建personalData方法。具体代码如下:
<?php
/*** 个人信息控制-也就是登录者信息及角色对外方法* User: 龙哥·三年风水* Date: 2024/10/30* Time: 14:18*/
namespace app\controller\permission;
use app\controller\Base;
class Member extends Base
{/*** 获取个人信息* User: 龙哥·三年风水* Date: 2024/10/30* Time: 14:23* @ return \think\response\Json*/public function personalData(){$data = [];$data['username'] = $this->username;$data['avatar'] = $this->avatar;$data['email'] = $this->email;$data['realname'] = $this->realname;return succ('操作成功',$data);}
}
二、nginx黑名单开发
因nginx自身是没有redis及rsa扩展使用的,所以我安装的不是nginx,而是openresty,他是有带resty扩展的。如果不会安装openresty,可以参照《centos7 二进制安装openresty》、《配置openresty》以及《openresty安全机制-白名单》三篇文章进行安装配置。
1、引入扩展
--引入Redis
local redis = require "resty.redis";
--引入rsa
local rsa = require "resty.rsa";
2、配置redis
--Redis链接ip
local ip = "172.20.36.144"
--Redis链接端口
local port = 6379
--Redis连接密码
local pass = "QXtr@@PxjoLenGon"
3、在对应的Redis库里面添加公钥字符串
我不管是在应用程序里面还是在本机制里面,都采用的是Redis第0号库的black-list库中哈,所有的非正常访问系统的IP都在black-list库中。
4、开发lua对应的Redis授权
--鉴权Redis
local function connAuth()local red = redis:new();local connCount, err = red:connect(ip, port);if not connCount thenngx.say("failed to connect: ", err)close_redis(red)returnendred:set_timeouts(2000);local ok, err = red:auth(pass)if not ok thenngx.say("failed to auth: ", err)close_redis(red)returnendreturn red
end
5、开发lua对应的Redis关闭
--关闭Redis
local function close_redis(red)if not red thenreturnend--释放连接(连接池实现)local pool_max_idle_time = 10000local pool_size = 100local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)if not ok thenngx.say("set keepalive error : ", err)end
end
6、开发获取请求者IP
--获取请求者IP
local function getIp()local clientIP = ngx.req.get_headers()["X-Real-IP"]if clientIP == nil thenclientIP = ngx.req.get_headers()["x_forwarded_for"]endif clientIP == nil thenclientIP = ngx.var.remote_addrendreturn clientIP
end
--获取用户访问IP
local clientIP = getIp();
--封禁token时间(秒)
local token_block_time= 120
--指定token访问频率计数最大值(次)
local token_max_count = 3
7、开发空方法
--如果数据为空的情况下
local function is_empty(value)if type(value) == "table" thenreturn next(value) == nilelseif type(value) == "string" thenreturn #value == 0elseif type(value) == "nil" thenreturn trueendreturn false
end
8、过滤特殊字符串
--过滤特殊字符串(只保留字母与数字,字母不区分大小写)
local function filter_special_chars(s)local ss = {}local k = 1while true doif k > #s then break endlocal c = string.byte(s,k)if not c then break endif c<192 thenif (c>=48 and c<=57) or (c>= 65 and c<=90) or (c>=97 and c<=122) thentable.insert(ss, string.char(c))endk = k + 1endendreturn table.concat(ss)
end
9、组合开发黑名单机制
--引入Redis
local redis = require "resty.redis";
--引入rsa
local rsa = require "resty.rsa";
--Redis链接ip
local ip = "172.20.36.144"
--Redis链接端口
local port = 6379
--Redis连接密码
local pass = "QXtr@@PxjoLenGon"
--鉴权Redis
local function connAuth()local red = redis:new();local connCount, err = red:connect(ip, port);if not connCount thenngx.say("failed to connect: ", err)close_redis(red)returnendred:set_timeouts(2000);local ok, err = red:auth(pass)if not ok thenngx.say("failed to auth: ", err)close_redis(red)returnendreturn red
end--关闭Redis
local function close_redis(red)if not red thenreturnend--释放连接(连接池实现)local pool_max_idle_time = 10000local pool_size = 100local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)if not ok thenngx.say("set keepalive error : ", err)end
end--获取请求者IP
local function getIp()local clientIP = ngx.req.get_headers()["X-Real-IP"]if clientIP == nil thenclientIP = ngx.req.get_headers()["x_forwarded_for"]endif clientIP == nil thenclientIP = ngx.var.remote_addrendreturn clientIP
end
--获取用户访问IP
local clientIP = getIp();
--封禁token时间(秒)
local token_block_time= 120
--指定token访问频率计数最大值(次)
local token_max_count = 3--如果数据为空的情况下
local function is_empty(value)if type(value) == "table" thenreturn next(value) == nilelseif type(value) == "string" thenreturn #value == 0elseif type(value) == "nil" thenreturn trueendreturn false
end--过滤特殊字符串(只保留字母与数字,字母不区分大小写)
local function filter_special_chars(s)local ss = {}local k = 1while true doif k > #s then break endlocal c = string.byte(s,k)if not c then break endif c<192 thenif (c>=48 and c<=57) or (c>= 65 and c<=90) or (c>=97 and c<=122) thentable.insert(ss, string.char(c))endk = k + 1endendreturn table.concat(ss)
end--如果头部信息没有指定的参数或是指定参数的值无法解析,加入IP黑名单
--如果同样的头部参数键在封禁token时间内连续访问指定token访问频率计数最大值次以上,加入IP黑名单----暂时还没有开发,开发测试好后,将重新更新
local function set_blacklist()local header = ngx.req.get_headers();local red = connAuth();local token, err = header["Authorization"];-- 如果参数为空的情况下if not token thenlocal res, err = red:sismember('black-list', clientIP);if res ~= 1 thenred:sadd('black-list', clientIP)endclose_redis(red)return ngx.exit(401)else-- 如果参数值为空的情况下if is_empty(token) thenlocal res, err = red:sismember('black-list', clientIP);if res ~= 1 thenred:sadd('black-list', clientIP)endclose_redis(red)return ngx.exit(401)end-- 如果参数值采用base64解析不开的情况下local encrypted, err = tostring(ngx.decode_base64(token))if not encrypted thenlocal res, err = red:sismember('black-list', clientIP);if res ~= 1 thenred:sadd('black-list', clientIP)endclose_redis(red)return ngx.exit(401)end-- 采用rsa技术解析token base64过后的值内容local priv_key = '-----BEGIN PRIVATE KEY-----\n' ..red:get('priv_key_cluster_control')..'\n-----END PRIVATE KEY-----';local priv, err = rsa:new({private_key = priv_key})local dst, err = rsa.decrypt(priv, encrypted)if not dst thenlocal res, err = red:sismember('black-list', clientIP);if res ~= 1 thenred:sadd('black-list', clientIP)endclose_redis(red)return ngx.exit(401)endend
end-- 查看是否在黑名单里面
local function get_blacklist()local red = connAuth();local res, err = red:sismember('black-list', clientIP);if res == 1 thenclose_redis(red);return ngx.exit(401);endclose_redis(red);
endget_blacklist();
set_blacklist();
10、将开发好的lua文件也一并上传到网站目录中,然后更改nginx应用配置文件,然后重新启动nginx,代码如下:
server {listen 80;server_name controlapi.yuanlongsoftware.cn;error_log /data/nginx/controlapi.yuanlongsoftware.cn80_error.log crit;access_log /data/nginx/controlapi.yuanlongsoftware.cn80_acess_$logdate.log access-upstream;lua_code_cache off;autoindex off;server_tokens off;error_page 401 /401.html;location / {if ($request_method ~* OPTIONS) {return 200;}access_by_lua_file /data/wwwroot/teach/group_control/cluster_control/rsa-cluster-control.lua;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;add_header 'Access-Control-Allow-Credentials' 'true';add_header Access-Control-Allow-Origin "$http_origin";add_header Access-Control-Allow-Headers 'X-Requested-With,Cache-Control,Content-Type,Authorization';add_header Cache-Control no-cache;add_header 'Access-Control-Allow-Methods' 'GET, POST';proxy_pass http://controlapi;}location = /401.html {root "/data/wwwroot/error";}
}
三、测试
1、登录后用token去获取一下用户信息接口,采用apipost工具测试

2、采用同一个token再次去获取一下用户信息接口,采用apipost工具再次测试

3、采用同一个token再次去获取一下用户信息接口,采用apipost工具再次测试

第二次以后,就是openresty直接返回咯,因lua去检测是发现他就在黑名单中,就直接返回。
其实后期我还会出对应的精简文章,也就是优化过后的文章。
四、提前说明
明后天将带来管理员功能开发、角色功能开发、菜单功能开发以及上传文件开发
相关文章:
群控系统服务端开发模式-应用开发-业务架构逻辑开发第一轮测试
整个系统的第一个层次已经开发完毕,已经有简单的中控,登录、退出、延迟登录时长、黑名单、数据层封装、验证层封装、RSA加解密、Redis等功能,还缺获取个人、角色按钮权限、角色菜单权限功能。角色按钮权限以及角色菜单权限等明后天开发&#…...
git 怎么保留某个文件夹忽略其下面的所有文件?
在 Git 中,如果你想要保留某个文件夹(比如 folder/)但忽略其下面的所有文件,可以使用 .gitignore 文件来实现。需要注意的是,Git 不会自动创建空目录。因此,为了让 Git 记录这个空目录,你需要在…...
Linux Shell 实现一键部署mariadb11.6
mariadb MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品。在存储引擎方面,使用XtraDB来代替MySQL的InnoDB。 MariaDB由MySQL的创始人Michael Widenius主导开发…...
Servlet 3.0 注解开发
文章目录 Servlet3.0注解开发修改idea创建注解的servlet模板内容讲解 关于servlet3.0注解开发的疑问_配置路径省略了属性urlPatterns内容讲解内容小结 Servlet3.0注解开发 【1】问题 说明:之前我们都是使用web.xml进行servlet映射路径的配置。这样配置的弊端&…...
rom定制系列------红米note8_miui14安卓13定制修改固件 带面具root权限 刷写以及界面预览
💝💝💝红米note8机型代码:ginkgo。高通芯片。此固件官方最终版为稳定版12.5.5安卓11的版本。目前很多工作室需要高安卓版本的固件来适应他们的软件。并且需要root权限。根据客户要求。修改固件为完全root。并且修改为可批量刷写的…...
Kaspa钱包ts代码封装
文章目录 1. 配置wasm2. 钱包地址创建3. KAS转账&余额查询4. KRC-20 处理5. 使用demo 1. 配置wasm 下载wasm地址:https://kaspa.aspectron.org/nightly/downloads/ 在项目根目录下添加wasm目录, 将下载的wasm文件中web目录下kaspa和kaspa-dev文件家…...
MySQL 数据库中 MyISAM 和 InnoDB 的区别:深入解析
MySQL 是目前最流行的开源数据库管理系统之一,支持多种存储引擎,其中最常用的就是 MyISAM 和 InnoDB。这两种存储引擎各有其特点,适用于不同的使用场景。理解它们之间的区别有助于数据库开发者和管理者根据应用需求选择合适的存储引擎。本文将…...
python中怎样实现闭包?
在Python中,闭包是指一个函数可以访问其自身范围之外的变量,即可以访问其外部函数作用域中的变量。要实现一个闭包,可以按照以下步骤进行: 内部函数引用外部函数的变量:在外部函数中定义一个内部函数,并在…...
论文阅读:MultiUI 利用网页UI进行丰富文本的视觉理解
《HARNESSING WEBPAGE UIS FOR TEXT-RICH VISUAL UNDERSTANDING》 利用网页UI进行丰富文本的视觉理解 总结 grounding和QA部分的数据集占比较大、同时消融实验显示其作用相对较大,并且grounding部分作用和效果呈现scaling正相关提供了很多web数据处理成多模态训练…...
【云原生】云原生后端详解:架构与实践
目录 引言一、云原生后端的核心概念1.1 微服务架构1.2 容器化1.3 可编排性1.4 弹性和可伸缩性 二、云原生后端的架构示意图三、云原生后端的最佳实践3.1 使用服务网格3.2 监控与日志管理3.3 CI/CD 流水线3.4 安全性 总结参考资料 引言 随着云计算的迅猛发展,云原生…...
MySQL覆盖索引
覆盖索引(Covering Index)是数据库优化中的一种重要技术 覆盖索引是指一个查询语句在执行时,所需的数据可以完全通过索引来获取,而无需访问实际的数据行。也就是说,查询语句所需的列都包含在了创建的索引中,…...
「C/C++」C/C++ 之 循环结构详解
✨博客主页何曾参静谧的博客📌文章专栏「C/C」C/C程序设计📚全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…...
json-server的基本使用
一、json-server工具的使用 可以快速的搭建符合RESTful API服务。返回符合RESTful规范的数据; 1、全局引入json-server包 npm install -g json-server2、创建json格式的db.json文件 {"jsonData": [{"name": "小明"}] }3、在json文…...
华为配置BFD状态与接口状态联动实验
组网图形 图1 配置BFD状态与接口状态联动组网图 BFD简介配置注意事项组网需求配置思路操作步骤配置文件 BFD简介 为了减小设备故障对业务的影响,提高网络的可靠性,网络设备需要能够尽快检测到与相邻设备间的通信故障,以便及时采取措施&…...
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-22
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-22 目录 文章目录 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-22目录1. PoisonedRAG: Knowledge corruption attacks to retrieval-augmented generation of large language models摘要创新点…...
理解消息队列
消息队列(Message Queue)有下面四大作用: 解耦。几个业务系统之间可以通过 MQ 解耦,例如做数据同步数据的顺序性和可恢复性异步通讯缓冲能力 理解 MQ MQ 的前两个特点且不说,我们看看另外两个的。 异步通讯&#x…...
!什么,matlab也有网页版了
已经脱离matlab一下下几天的困境了,是的,matlab也有网页版了 附上网址: MATLAB Login | MATLAB & Simulink...
安卓屏幕息屏唤醒
背景,今天遇项目需要,需要在下载在后台任务运行时(如下载、上传或进行长时间计算),保持 CPU 活动,然后就写了这个实现方法,废话不多说上代码 第一步,再清单AndroidManifest文件声明权…...
类文件具有错误的版本 61.0, 应为 55.0
启动项目的时候报这个错误. 项目所使用的redis版本是jdk17的,而我使用的是Java11.所以要将redis版本降下来。 另一种方式就是修改jdk的版本,在设置修改编译版本,在版本控制里面修改jdk的版本。...
vue点击菜单,出现2个相同tab,啥原因
点击菜单,出现相同的tab 出现的原因: 1.组件中的name 和配置路由文件js, 的大小写不一致导致 2、跳转的路由整个地址,大小写不一致大致...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
Yii2项目自动向GitLab上报Bug
Yii2 项目自动上报Bug 原理 yii2在程序报错时, 会执行指定action, 通过重写ErrorAction, 实现Bug自动提交至GitLab的issue 步骤 配置SiteController中的actions方法 public function actions(){return [error > [class > app\helpers\web\ErrorAction,],];}重写Error…...
LeetCode - 148. 排序链表
目录 题目 思路 基本情况检查 复杂度分析 执行示例 读者可能出的错误 正确的写法 题目 148. 排序链表 - 力扣(LeetCode) 思路 链表归并排序采用"分治"的策略,主要分为三个步骤: 分割:将链表从中间…...
