群控系统服务端开发模式-应用开发-业务架构逻辑开发第一轮测试

        整个系统的第一个层次已经开发完毕,已经有简单的中控,登录、退出、延迟登录时长、黑名单、数据层封装、验证层封装、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 then
		ngx.say("failed to connect: ", err)
		close_redis(red)
		return
	end
	red:set_timeouts(2000);
	local ok, err = red:auth(pass)
	if not ok then
		ngx.say("failed to auth: ", err)
		close_redis(red)
		return
	end
	return red
end

        5、开发lua对应的Redis关闭

--关闭Redis
local function close_redis(red)
    if not red then
        return
    end
    --释放连接(连接池实现)
    local pool_max_idle_time = 10000
    local pool_size = 100
    local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
    if not ok then
        ngx.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 then
        clientIP = ngx.req.get_headers()["x_forwarded_for"]
    end
    if clientIP == nil then
        clientIP = ngx.var.remote_addr
    end
    return 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" then
        return next(value) == nil
    elseif type(value) == "string" then
        return #value == 0
    elseif type(value) == "nil" then
        return true
    end
        return false
end

        8、过滤特殊字符串

--过滤特殊字符串(只保留字母与数字,字母不区分大小写)
local function filter_special_chars(s)
    local ss = {}
    local k = 1
    while true do
        if k > #s then break end
        local c = string.byte(s,k)
        if not c then break end
        if c<192 then
            if (c>=48 and c<=57) or (c>= 65 and c<=90) or (c>=97 and c<=122) then
                table.insert(ss, string.char(c))
            end
            k = k + 1
        end
    end
    return 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 then
		ngx.say("failed to connect: ", err)
		close_redis(red)
		return
	end
	red:set_timeouts(2000);
	local ok, err = red:auth(pass)
	if not ok then
		ngx.say("failed to auth: ", err)
		close_redis(red)
		return
	end
	return red
end

--关闭Redis
local function close_redis(red)
    if not red then
        return
    end
    --释放连接(连接池实现)
    local pool_max_idle_time = 10000
    local pool_size = 100
    local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
    if not ok then
        ngx.say("set keepalive error : ", err)
    end
end

--获取请求者IP
local function getIp()
    local clientIP = ngx.req.get_headers()["X-Real-IP"]
    if clientIP == nil then
        clientIP = ngx.req.get_headers()["x_forwarded_for"]
    end
    if clientIP == nil then
        clientIP = ngx.var.remote_addr
    end
    return 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" then
        return next(value) == nil
    elseif type(value) == "string" then
        return #value == 0
    elseif type(value) == "nil" then
        return true
    end
        return false
end

--过滤特殊字符串(只保留字母与数字,字母不区分大小写)
local function filter_special_chars(s)
    local ss = {}
    local k = 1
    while true do
        if k > #s then break end
        local c = string.byte(s,k)
        if not c then break end
        if c<192 then
            if (c>=48 and c<=57) or (c>= 65 and c<=90) or (c>=97 and c<=122) then
                table.insert(ss, string.char(c))
            end
            k = k + 1
        end
    end
    return 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 then
        local res, err =  red:sismember('black-list', clientIP);
        if res ~= 1 then
            red:sadd('black-list', clientIP)
        end
        close_redis(red)
        return ngx.exit(401)
    else
        -- 如果参数值为空的情况下
        if is_empty(token) then
            local res, err =  red:sismember('black-list', clientIP);
            if res ~= 1 then
                red:sadd('black-list', clientIP)
            end
            close_redis(red)
            return ngx.exit(401)
        end
        -- 如果参数值采用base64解析不开的情况下
        local encrypted, err = tostring(ngx.decode_base64(token))
        if not encrypted then
            local res, err =  red:sismember('black-list', clientIP);
            if res ~= 1 then
                red:sadd('black-list', clientIP)
            end
            close_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 then
            local res, err =  red:sismember('black-list', clientIP);
            if res ~= 1 then
                red:sadd('black-list', clientIP)
            end
            close_redis(red)
            return ngx.exit(401)
        end
    end
end

-- 查看是否在黑名单里面
local function get_blacklist()
    local red = connAuth();
    local res, err =  red:sismember('black-list', clientIP);
    if res == 1 then
        close_redis(red);
        return ngx.exit(401);
    end
    close_redis(red);
end

get_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去检测是发现他就在黑名单中,就直接返回。

        其实后期我还会出对应的精简文章,也就是优化过后的文章。

四、提前说明

        明后天将带来管理员功能开发、角色功能开发、菜单功能开发以及上传文件开发

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/907618.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

react基础之reactHooks

文章目录 React Hooks 使用指南常用 Hooks使用规则 小结 React Hooks 使用指南 React Hooks 是 React 16.8 引入的一种新特性&#xff0c;允许在函数组件中使用状态和其他 React 特性&#xff0c;而无需编写类组件。以下是一些基础的 Hooks 及其使用规则。 常用 Hooks useSta…

桑基图在医学数据分析中的更复杂应用示例

桑基图&#xff08;Sankey Diagram&#xff09;能够有效地展示复杂的流动关系&#xff0c;特别适合用于医学数据分析中的多种转归和治疗路径的可视化。接下来&#xff0c;我们将构建一个稍微复杂的示例&#xff0c;展示不同疾病患者在治疗过程中的流动&#xff0c;以及他们的治…

Android15音频进阶之Cuttlefish搭建音频开发环境(九十二)

简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【原创干货持续更新中……】🚀 优质视频课程:AAOS车载系统+…

koa + sequelize做距离计算(MySql篇)

1.核心思路 1.利用sequelize的fn方法调用MySql原生函数&#xff08;ST_Distance_Sphere 、POINT&#xff09; 2.通MOD过函数将查询到的距离除以1000&#xff0c;这样km就变成了米 &#xff0c;利用FOMAT函数将查询到的结果精确到两位小数 3.这里利用到了MySql的原生函数&…

【Oracle APEX开发小技巧10】CSS样式控制交互式报表列宽和自动换行效果

在实际开发中使用交互式报表可能会出现某些字段的列宽过长&#xff0c;某些字段的列宽只有缩到一角的情况&#xff0c;那么如何解决这种情况呢&#xff1f;有没有方法可以控制交互式报表的列宽呢&#xff1f;下面就来介绍一下解决方法&#xff1a; 页设置-页-CSS-内嵌 输入如下…

IO详解(BIO、NIO、实战案例、底层原理刨析)

文章目录 IO详解&#xff08;BIO、NIO、实战案例、底层原理刨析&#xff09;&#x1f30e; IO&#x1fa90; 同步、异步、阻塞、非阻塞⚡ BIO&#x1f47d; 简介&#x1f60e; 案例 &#x1f680; NIO✈️ 介绍&#x1f697; Buffer&#xff08;缓冲&#xff09;&#x1f6f8; …

#渗透测试#SRC漏洞挖掘# 信息收集-Shodan之搜索语法进阶

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

Python复习1:

一、数据类型 1.数字&#xff1a;int、float、bool 2.字符串&#xff1a;string 3.列表&#xff1a;list 4.集合&#xff1a;set 5.字典&#xff1a;dictionary 二、Test 1.print输出固定格式 num110 str1"hello world" #输出的固定格式 print("num1%d&…

【MyBatis源码】BoundSql分析

基础 BoundSql是对SQL语句及参数信息的封装&#xff0c;它是SqlSource解析后的结果。Executor组件并不是直接通过StaticSqlSource对象完成数据库操作的&#xff0c;而是与BoundSql交互。BoundSql是对Executor组件执行SQL信息的封装&#xff0c;具体实现代码如下&#xff1a; …

Python爬虫抓取三个网站上的英语每日一句

一、引言 大学英语学习需要巩固高中语法&#xff0c;补充四六级词汇&#xff0c;增加英语语感&#xff0c;提升英语的运用能力。学好英语有很多种方法&#xff0c;采用句子来突破英语语法、词汇、口语和听力的方法简单有效&#xff0c;值得提倡。李阳就是采用这种方法来教授英…

三相LCL并网逆变器—为什么采用LCL滤波器

1.为什么需要滤波器 当前并网逆变器大多采用脉冲宽度调制(PWM)技术&#xff0c;导致桥臂输出的电压中存在开关频率及倍数频率次的谐波电压&#xff0c;进而使得输出到电网的电流中含有谐波。从电网的角度来看&#xff0c;是不希望系统内含有高次谐波的&#xff0c;因为这会影响…

【STM32】按键控制LED 光敏传感器控制蜂鸣器

文章目录 前置知识按键介绍传感器模块硬件电路按键硬件电路传感器模块硬件电路 C语言数据类型在Keil中的对应写法C语言枚举 按键控制LED接线图Hardware文件夹&#xff08;模块化编程&#xff09;LED驱动程序封装Key(按键)驱动程序封装 main.c源文件 光敏传感器控制蜂鸣器接线图…

飞书API-获取tenant_access_token

1.在飞书工作台创建应用&#xff0c;跳到开发者后台&#xff0c;选创建企业自建应用 2.设置并发布应用 必须要发布应用才可以开始使用了&#xff01;&#xff01;&#xff01; 3.调用获取token的API 参考链接&#xff1a; 开发文档 - 飞书开放平台https://open.feishu.cn/do…

SpringBoot篇(自动装配原理)

目录 一、自动装配机制 1. 简介 2. 自动装配主要依靠三个核心的关键技术 3. run()方法加载启动类 4. 注解SpringBootApplication包含了多个注解 4.1 SpringBootConfiguration 4.2 ComponentScan 4.3 EnableAutoConfiguration 5. SpringBootApplication一共做了三件事 …

Rust 力扣 - 48. 旋转图像

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们可以将原矩阵进行水平翻转&#xff0c;然后在沿主对角线进行翻转&#xff0c;就能完成原矩阵沿顺时针方向旋转90o的变换 题解代码 impl Solution {pub fn rotate(matrix: &mut Vec<Vec<i32>&…

ima.copilot:智慧因你而生

在数字化时代&#xff0c;信息的获取、处理和创作已经成为我们日常工作和学习中不可或缺的一部分。腾讯公司推出的ima.copilot&#xff08;简称ima&#xff09;正是为了满足这一需求&#xff0c;它是一款由腾讯混元大模型提供技术支持的智能工作台产品&#xff0c;旨在通过智能…

使用 PyCharm 构建 FastAPI 项目:零基础入门 Web API 开发

使用 PyCharm 构建 FastAPI 项目&#xff1a;零基础入门 Web API 开发 本文提供了一份完整的 FastAPI 入门指南&#xff0c;涵盖从环境搭建、依赖安装到创建并运行一个简单的 FastAPI 应用的各个步骤。通过 FastAPI 和 Uvicorn&#xff0c;开发者可以快速构建现代化的 Web API…

练习LabVIEW第三十五题

学习目标&#xff1a; 刚学了LabVIEW&#xff0c;在网上找了些题&#xff0c;练习一下LabVIEW&#xff0c;有不对不好不足的地方欢迎指正&#xff01; 第三十五题&#xff1a; 使用labview模拟一个3-8译码器 开始编写&#xff1a; 用LabVIEW做3-8译码器首先要知道它是个啥…

【流量控制】之创建和管理前缀列表

前缀列表是包含一个或多个CIDR地址块的集合。您可以自主创建前缀列表并对其进行管理。在创建过程中&#xff0c;您可以将现有的前缀列表克隆&#xff08;复制&#xff09;到指定地域&#xff08;同地域或跨地域&#xff09;&#xff0c;让操作更加便捷。本文介绍如何使用专有网…

数据库作业5

1&#xff0c;建立触发器&#xff0c;订单表中增加订单数量后&#xff0c;商品表商品数量同步减少对应的商品订单出数量,并测试 测试&#xff1a; 2.建立触发器&#xff0c;实现功能:客户取消订单&#xff0c;恢复商品表对应商品的数量 测试 3.建立触发器&#xff0c;实现功能:…