通过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. 安全性:确保传输过程中数据的安全,防止恶意攻击和绕过验证。

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

相关推荐
蓁蓁啊9 小时前
GIT使用SSH 多账户配置
运维·git·ssh
程序猿小三11 小时前
Linux下基于关键词文件搜索
linux·运维·服务器
虚拟指尖12 小时前
Ubuntu编译安装COLMAP【实测编译成功】
linux·运维·ubuntu
椎49513 小时前
苍穹外卖前端nginx错误之一解决
运维·前端·nginx
刘某的Cloud13 小时前
parted磁盘管理
linux·运维·系统·parted
极验13 小时前
iPhone17实体卡槽消失?eSIM 普及下的安全挑战与应对
大数据·运维·安全
爱倒腾的老唐13 小时前
24、Linux 路由管理
linux·运维·网络
yannan2019031313 小时前
Docker容器
运维·docker·容器
_清浅14 小时前
计算机网络【第六章-应用层】
运维·服务器·计算机网络
正在努力的小河14 小时前
Linux 自带的 LED 灯驱动实验
linux·运维·服务器