通过nginx弄一个滑块加图片的人机验证

要通过 Nginx 实现滑块加图片的人机验证,你可以利用 OpenResty 和 Lua 脚本来生成并处理滑块验证码。滑块验证码的基本流程包括以下步骤:

  1. 生成带有缺口的图片。
  2. 生成缺口图片。
  3. 前端展示图片和滑块。
  4. 用户滑动滑块到正确位置。
  5. 服务器验证滑块位置。

以下是一个示例的实现步骤:

1. 安装 OpenResty 和 Lua 库

首先,安装 OpenResty 和必要的 Lua 库。

sh 复制代码
# For Debian/Ubuntu
sudo apt-get install openresty

# For CentOS/RHEL
sudo yum install openresty

# Install LuaRocks
sudo apt-get install luarocks
sudo luarocks install lua-resty-string
sudo luarocks install lua-resty-random
sudo luarocks install gd

2. 配置 Nginx

编辑你的 nginx.conf 文件,添加以下配置:

nginx 复制代码
worker_processes 1;

events {
    worker_connections 1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    server {
        listen       8080;
        server_name  localhost;

        location /captcha {
            content_by_lua_file /path/to/your/captcha.lua;
        }

        location /validate {
            content_by_lua_file /path/to/your/validate.lua;
        }
    }
}

3. 编写 Lua 脚本

captcha.lua:生成带有缺口的图片和缺口图片

lua 复制代码
local gd = require "resty.gd"
local random = require "resty.random"
local str = require "resty.string"

local function generate_code()
    return math.random(100, 300) -- 随机生成一个缺口位置
end

local function create_captcha()
    local img = gd.createFromPng("/path/to/your/background.png")
    local img_width, img_height = img:sizeXY()
    local gap_size = 50

    local gap_x = generate_code()
    local gap_y = img_height / 2 - gap_size / 2

    local gap_img = gd.createTrueColor(gap_size, gap_size)
    gap_img:copy(img, 0, 0, gap_x, gap_y, gap_size, gap_size)

    local white = img:colorAllocate(255, 255, 255)
    img:filledRectangle(gap_x, gap_y, gap_x + gap_size, gap_y + gap_size, white)

    local img_str = img:pngStr()
    local gap_img_str = gap_img:pngStr()

    return img_str, gap_img_str, gap_x
end

local img_str, gap_img_str, gap_x = create_captcha()

ngx.header.content_type = "application/json"
ngx.say('{"background":"'.. ngx.encode_base64(img_str) ..'", "gap":"'.. ngx.encode_base64(gap_img_str) ..'", "gap_x":'.. gap_x ..'}')

validate.lua:验证用户滑动的位置是否正确

lua 复制代码
local cjson = require "cjson"

ngx.req.read_body()
local args = ngx.req.get_post_args()
local user_gap_x = tonumber(args.gap_x)

-- 从 Redis 或其他存储中获取正确的 gap_x
local correct_gap_x = 150 -- 示例值,实际应从存储中获取

if math.abs(user_gap_x - correct_gap_x) < 5 then
    ngx.say(cjson.encode({ success = true }))
else
    ngx.say(cjson.encode({ success = false }))
end

4. 前端代码

前端使用 JavaScript 实现滑块和图片展示:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>滑块验证码</title>
    <style>
        .captcha-container {
            position: relative;
            width: 300px;
            height: 150px;
        }
        .captcha-image {
            width: 100%;
            height: 100%;
        }
        .slider {
            position: absolute;
            bottom: 10px;
            left: 0;
            width: 50px;
            height: 50px;
            background-color: #fff;
            border: 1px solid #ccc;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div class="captcha-container" id="captcha-container">
        <img src="" id="captcha-image" class="captcha-image">
        <div id="slider" class="slider"></div>
    </div>

    <script>
        async function loadCaptcha() {
            const response = await fetch('/captcha');
            const data = await response.json();
            const bgImage = 'data:image/png;base64,' + data.background;
            const gapImage = 'data:image/png;base64,' + data.gap;

            document.getElementById('captcha-image').src = bgImage;
            // Render the gap image in a canvas or any other way

            return data.gap_x;
        }

        document.addEventListener('DOMContentLoaded', async () => {
            const correctGapX = await loadCaptcha();
            const slider = document.getElementById('slider');
            let isDragging = false;
            let startX;

            slider.addEventListener('mousedown', (event) => {
                isDragging = true;
                startX = event.clientX;
            });

            document.addEventListener('mousemove', (event) => {
                if (isDragging) {
                    const moveX = event.clientX - startX;
                    slider.style.transform = `translateX(${moveX}px)`;
                }
            });

            document.addEventListener('mouseup', async (event) => {
                if (isDragging) {
                    isDragging = false;
                    const moveX = event.clientX - startX;

                    const response = await fetch('/validate', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ gap_x: moveX })
                    });

                    const result = await response.json();
                    if (result.success) {
                        alert('验证成功');
                    } else {
                        alert('验证失败');
                    }
                }
            });
        });
    </script>
</body>
</html>

5. 注意事项

  1. 路径配置:确保图片路径和 Lua 文件路径正确。
  2. 前端滑块:实际使用时可能需要更复杂的前端代码来处理滑块移动和验证逻辑。
  3. 存储机制:为了简单起见,示例代码没有实现存储机制。在实际应用中,可以使用 Redis 或其他存储系统来存储和验证 gap_x 值。
  4. 安全性:确保传输过程中数据的安全,防止恶意攻击和绕过验证。

通过这些步骤,你可以实现一个基本的滑块验证码系统。如果需要更复杂和高效的验证码系统,可以考虑使用现有的解决方案或服务。

相关推荐
虎头金猫5 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
还是大剑师兰特5 天前
解决nginx错误:http://localhost:7000正常,http://localhost:7000/map 报错404
nginx·大剑师
AI职业加油站5 天前
AI智能体应用工程师证书:政策红利下的职业新风口
大数据·运维·人工智能·学习·职场发展
此冬歌咏5 天前
K8s 节点故障实战:优雅驱逐 31 秒,硬故障 331 秒,以及那个永远 Pending 的 Pod
运维·k8s
xing-xing5 天前
Docker容器中Nginx站点根目录网页配置访问
nginx·docker
-梅5 天前
linux(8) 软硬链接
linux·运维·服务器
张洛闻Eren5 天前
k8s云原生【第十课】:水平 Pod 自动扩缩容
运维·数据库·云原生·kubernetes·github
其实防守也摸鱼5 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
布裘5 天前
【银河麒麟】V4桌面图标消失,右击鼠标没反应排查
运维·银河麒麟·桌面环境
懂软件的胡子个哥5 天前
微信机器人为什么需要“回复候选”而不是所有 AI 内容直接发送
运维·微信·自动化·wechatapi·个人微信号二次开发