增加图片验证码生成业务逻辑相关文件,并编写接口用于测试使用

This commit is contained in:
wanglei 2025-11-21 14:33:56 +08:00
parent 7c22e73f66
commit 4869731a99
4 changed files with 141 additions and 37 deletions

View File

@ -48,6 +48,11 @@ location /yum/v1/system/users {
content_by_lua_file '${APP_PATH}/src/api/system/user.lua';
}
#登陆时图片验证码相关
location /yum/v1/system/captcha {
content_by_lua_file '${APP_PATH}/src/api/system/captcha.lua';
}
######################################################
### oauth2.0 + openIDC 接口文件处理 ###
######################################################

View File

@ -0,0 +1,43 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by admin.
--- DateTime: 2025/11/21 11:50
--- 验证码图片接口
--解析url路由过滤库
local radix = require("resty.radixtree")
--数据表业务处理
local systemCaptcha = require("service.system.captcha")
--定义相关路由前端接口url地址
local routes = {
--验证码图片相关路由接口
{
paths = { "/yum/v1/system/captcha" },
methods = { "GET" },
handler = systemCaptcha.getCaptcha,
},
}
-- 初始化路由
local rx, err = radix.new(routes)
if not rx then
ngx.say("Not Found")
ngx.exit(ngx.HTTP_NOT_FOUND)
end
--获取访问的uri地址
local uri = ngx.var.uri
local opts = {
host = ngx.var.host,
method = ngx.var.request_method,
remote_addr = ngx.var.remote_addr,
matched = {}
}
-- 进行路由匹配和相关函数调用
local ok = rx:dispatch(uri, opts, opts.matched)
if not ok then
ngx.say("Not Found")
ngx.exit(ngx.HTTP_NOT_FOUND)
end

View File

@ -0,0 +1,44 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by admin.
--- DateTime: 2025/11/21 11:55
--- 验证码相关函数
local _M = {}
local status = require("util.status")
local resp = require("util.response")
local genpic = require("util.generatechaptcha")
local red = require("share.redis")
--生成图片文件
function _M.getCaptcha()
local filename, base64_data, captchaText = genpic.get_captcha_base64()
--将文件名存储到redis中 超时时间5分钟
local key = "captcha-"..filename
red:set(key, captchaText)
red:expire(key, 5 * 60)
-- 4.返回结果
local ret = {
picgid = filename,
pic = base64_data
}
resp:response(status.SUCCESS, ret)
end
--验证图片上的验证码
function _M.checkCaptcha()
end
--验证码删除
function _M.deleteCaptcha()
--获取请求中参数
local args = ngx.req.get_uri_args()
--其中image为要删除的验证码图片的picgid。
local picgid = args["picgid"]
red:del(picgid)
end
return _M

View File

@ -12,54 +12,66 @@ local _M = {}
--在32个备选字符中随机筛选4个作为captcha字符串
local dict = {'A','B','C','D','E','F','G','H','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z','2','3','4','5','6','7','8','9'}
function _M.getChaptcha()
local stringmark = ""
for i = 1, 4 do
stringmark = stringmark..dict[math.random(1,32)]
end
-- 生成验证码图片
local function generate_captcha()
--图片基本info
local uid = uuid.generateUuid()
--picgid
local filename = "1"..uid..".png"
local filename = uid
--图片78x26
local xsize = 78
local ysize = 26
--字体大小
local wsize = 17.5
--干扰线(yes/no)
local line = "yes"
local width = 78
local height = 26
-- 创建画布
local im = gd.createTrueColor(width, height)
--创建面板
local im = gd.createTrueColor(xsize, ysize)
--定义颜色
-- 设置背景色(白色)
local white = im:colorAllocate(255, 255, 255)
im:filledRectangle(0, 0, width, height, white)
-- 设置文本颜色(黑色)
local black = im:colorAllocate(0, 0, 0)
local grey = im:colorAllocate(202, 202, 202)
local color = {}
for c = 1, 100 do
color[c] = im:colorAllocate(math.random(100), math.random(100), math.random(100))
-- 生成随机验证码4位数字字母
math.randomseed(os.time())
local captcha_text = ""
for i = 1, 4 do
captcha_text = captcha_text..dict[math.random(1,32)]
end
--画背景
x, y = im:sizeXY()
im:filledRectangle(0, 0, x, y, grey)
--画字符
-- 在图片上绘制验证码文本
gd.useFontConfig(true)
for i = 1, 4 do
k = (i - 1) * 16 + 3
im:stringFT(color[math.random(100)], "Arial:bold", wsize, math.rad(math.random(-10,10)), k, 22, string.sub(stringmark, i, i))
local char = string.sub(captcha_text, i, i)
local x = 10 + (i-1)*25 + math.random(-5,5)
local y = 10 + math.random(-5,5)
local angle = math.random(-20, 20)
im:stringFT(black, "Arial:bold", 18, angle, x, 30, char)
end
--干扰线点
if line == "yes" then
for j = 1, math.random(3) do
im:line(math.random(xsize), math.random(ysize), math.random(xsize), math.random(ysize), color[math.random(100)])
-- 添加干扰线
for i = 1, 5 do
local line_color = im:colorAllocate(math.random(0,255), math.random(0,255), math.random(0,255))
im:line(math.random(0, height), math.random(0, width), math.random(0,height), math.random(0, width), line_color)
end
for p = 1, 20 do
im:setPixel(math.random(xsize), math.random(ysize), color[math.random(100)])
-- 添加噪点
for i = 1, 100 do
local dot_color = im:colorAllocate(math.random(0,255), math.random(0,255), math.random(0,255))
im:setPixel(math.random(0, height), math.random(0, width), dot_color)
end
-- 将图片转换为PNG格式的二进制数据
local png_data = im:pngStr(75)
return filename, captcha_text, png_data
end
--流输出
local fp = im:pngStr(75)
return filename, fp
-- 生成验证码并返回Base64编码
function _M.get_captcha_base64()
local filename, captcha_text, png_data = generate_captcha()
if not png_data then
ngx.log(ngx.ERR, "Failed to generate captcha image")
return nil, nil, nil
end
-- 对图片数据进行Base64编码
local base64_data = ngx.encode_base64(png_data)
return filename, base64_data, captcha_text
end
return _M