增加swagger文档相关的文件,对修改的内容进行处理

This commit is contained in:
wanglei 2026-02-04 09:44:29 +08:00
parent e485444975
commit 61d1113cbe
38 changed files with 15831 additions and 166 deletions

View File

@ -8,7 +8,8 @@ events {
} }
http { http {
include mime.types;
default_type application/octet-stream;
##lua_need_request_body on; #开启读取请求体数据 ##lua_need_request_body on; #开启读取请求体数据
client_max_body_size 1024M; #允许最大100k的请求体 client_max_body_size 1024M; #允许最大100k的请求体
client_body_buffer_size 1024M; #设置缓冲区大小 client_body_buffer_size 1024M; #设置缓冲区大小
@ -42,20 +43,20 @@ http {
init_worker_by_lua_file '/home/frankly/work/AuthPlatform/src/init.lua'; init_worker_by_lua_file '/home/frankly/work/AuthPlatform/src/init.lua';
server { server {
listen 9080; listen 9081;
server_name 127.0.0.1; server_name 127.0.0.1;
default_type text/html; #default_type text/html;
location = /favicon.ico { #location = /favicon.ico {
log_not_found off; # log_not_found off;
access_log off; # access_log off;
} #}
## 应用路径 todo 路径问题 ## 应用路径 todo 路径问题
set $APP_PATH '/home/frankly/work/AuthPlatform'; set $APP_PATH '/home/frankly/work/AuthPlatform';
# 全局 CORS 配置 访问时允许跨域处理 # 全局 CORS 配置 访问时允许跨域处理
# 允许所有域跨域访问(不推荐,出于安全考虑应指定具体域名) # 允许所有域跨域访问(不推荐,出于安全考虑应指定具体域名)
add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Origin' '*';
# 允许特定域跨域访问(推荐) # 允许特定域跨域访问
#add_header 'Access-Control-Allow-Origin' 'https://xxx.com'; #add_header 'Access-Control-Allow-Origin' 'https://xxx.com';
# 允许的HTTP方法 # 允许的HTTP方法
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS'; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
@ -75,6 +76,21 @@ http {
#数据列表配置 #数据列表配置
include 'system/system.conf'; include 'system/system.conf';
# === Swagger UI ===
location /swagger/ {
allow 192.168.0.0/16;
allow 127.0.0.1;
deny all;
alias $APP_PATH/html/swagger/;
try_files $uri $uri/ /swagger/index.html;
}
# === OpenAPI JSON ===
location = /api-docs {
default_type application/json;
alias $APP_PATH/conf/openapi.json;
}
#测试接口配置 #测试接口配置
location /testTree { location /testTree {
content_by_lua_file '${APP_PATH}/src/test/testRadixtree.lua'; content_by_lua_file '${APP_PATH}/src/test/testRadixtree.lua';

59
conf/openapi.json Normal file
View File

@ -0,0 +1,59 @@
{
"openapi": "3.1.0",
"info": {
"title": "统一认证平台",
"description": "用于认证用户信息使用",
"version": "1.0.0"
},
"servers": [
{
"url": "http://192.168.0.69:9081"
}
],
"paths": {
"/yum/v1/users/{id}": {
"get": {
"tags": ["User API"],
"summary": "获取用户信息",
"operationId": "getUser",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "integer",
"minimum": 1
}
}
],
"responses": {
"200": {
"description": "成功返回用户",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"email": {
"type": "string"
}
}
}
}
}
},
"404": {
"description": "用户不存在"
}
}
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

60
html/swagger/index.html Normal file
View File

@ -0,0 +1,60 @@
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body
{
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
<script>
window.onload = function() {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
url: "swagger.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
});
// End Swagger UI call region
window.ui = ui;
};
</script>
</body>
</html>

126
html/swagger/index1.html Normal file
View File

@ -0,0 +1,126 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>API 文档 - OpenResty</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
<!-- ✨ 自定义美化样式 -->
<style>
/* 全局字体与间距 */
.swagger-ui {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif !important;
font-size: 14px !important;
}
/* 顶部标题 */
.swagger-ui .info h1 {
font-weight: 700 !important;
font-size: 28px !important;
color: #2c3e50 !important;
margin-bottom: 8px !important;
}
/* 操作块容器 */
.swagger-ui .opblock {
border-radius: 12px !important;
box-shadow: 0 4px 12px rgba(0,0,0,0.05) !important;
margin-bottom: 20px !important;
border-left: 0 !important;
}
/* HTTP 方法左侧彩色条 */
.swagger-ui .opblock-get { border-left: 5px solid #61affe !important; }
.swagger-ui .opblock-post { border-left: 5px solid #49cc90 !important; }
.swagger-ui .opblock-put { border-left: 5px solid #fca130 !important; }
.swagger-ui .opblock-delete { border-left: 5px solid #f93e3e !important; }
.swagger-ui .opblock-patch { border-left: 5px solid #50e3c2 !important; }
.swagger-ui .opblock-head { border-left: 5px solid #9012fe !important; }
/* 按钮圆角 */
.swagger-ui .btn {
border-radius: 6px !important;
font-weight: 600 !important;
padding: 6px 16px !important;
}
/* 参数表格 */
.swagger-ui table thead tr th {
background-color: #f8f9fa !important;
font-weight: 600 !important;
padding: 10px !important;
}
.swagger-ui table tbody tr td {
padding: 10px 8px !important;
border-bottom: 1px solid #eee !important;
}
/* 响应示例背景 */
.swagger-ui .microlight {
background: #f6f8fa !important;
border-radius: 8px !important;
padding: 14px !important;
font-size: 13px !important;
}
/* 搜索框 */
.swagger-ui .filter-container input {
border: 1px solid #ddd !important;
border-radius: 8px !important;
padding: 8px 12px !important;
width: 100% !important;
max-width: 300px !important;
}
/* 服务器列表 */
.swagger-ui .servers > div {
margin-bottom: 12px !important;
}
/* 滚动条优化(可选) */
*::-webkit-scrollbar {
width: 8px;
}
*::-webkit-scrollbar-track {
background: #f1f1f1;
}
*::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 4px;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="./swagger-ui-bundle.js"></script>
<script src="./swagger-ui-standalone-preset.js"></script>
<script>
window.onload = function() {
const ui = SwaggerUIBundle({
url: "/api-docs", // ← 指向你的 OpenAPI JSON
dom_id: '#swagger-ui',
deepLinking: true,
docExpansion: "list", // 默认展开所有接口
filter: true, // 启用搜索过滤
displayRequestDuration: true, // 显示请求耗时
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout",
// supportedSubmitMethods: [], // 生产环境取消注释以禁用 "Try it out"
});
window.ui = ui;
};
</script>
</body>
</html>

View File

@ -0,0 +1,75 @@
<!doctype html>
<html lang="en-US">
<head>
<title>Swagger UI: OAuth2 Redirect</title>
</head>
<body>
<script>
'use strict';
function run () {
var oauth2 = window.opener.swaggerUIRedirectOauth2;
var sentState = oauth2.state;
var redirectUrl = oauth2.redirectUrl;
var isValid, qp, arr;
if (/code|token|error/.test(window.location.hash)) {
qp = window.location.hash.substring(1);
} else {
qp = location.search.substring(1);
}
arr = qp.split("&");
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
qp = qp ? JSON.parse('{' + arr.join() + '}',
function (key, value) {
return key === "" ? value : decodeURIComponent(value);
}
) : {};
isValid = qp.state === sentState;
if ((
oauth2.auth.schema.get("flow") === "accessCode" ||
oauth2.auth.schema.get("flow") === "authorizationCode" ||
oauth2.auth.schema.get("flow") === "authorization_code"
) && !oauth2.auth.code) {
if (!isValid) {
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "warning",
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
});
}
if (qp.code) {
delete oauth2.state;
oauth2.auth.code = qp.code;
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
} else {
let oauthErrorMsg;
if (qp.error) {
oauthErrorMsg = "["+qp.error+"]: " +
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
(qp.error_uri ? "More info: "+qp.error_uri : "");
}
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "error",
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
});
}
} else {
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
}
window.close();
}
window.addEventListener('DOMContentLoaded', function () {
run();
});
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

9108
html/swagger/swagger.json Normal file

File diff suppressed because it is too large Load Diff

6019
html/swagger/swagger.yml Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -37,19 +37,19 @@ end
--根据应用id获取应用信息 --根据应用id获取应用信息
function _M.getSystemApplication(id) function _M.getSystemApplication(id)
return applicationModel.find(id) return applicationModel:find(id)
end end
--根据组织id获取应用信息 --根据组织id获取应用信息
function _M.getOrganizationApplication(id) function _M.getOrganizationApplication(id)
--todo --todo
return applicationModel.find(id) return applicationModel:find(id)
end end
--根据用户id获取应用信息 --根据用户id获取应用信息
function _M.getUserApplication(id) function _M.getUserApplication(id)
--todo --todo
return applicationModel.find(id) return applicationModel:find(id)
end end
--增加应用信息到数据表 --增加应用信息到数据表

View File

@ -34,7 +34,7 @@ end
--根据组织架构id获取组织架构信息 --根据组织架构id获取组织架构信息
function _M.getSystemDepartment(id) function _M.getSystemDepartment(id)
return departmentModel.find(id) return departmentModel:find(id)
end end
--增加组织架构息到数据表 --增加组织架构息到数据表

View File

@ -42,7 +42,7 @@ function _M.getSystemAccount(m)
local code, ret = accountDao.getSystemAccount(id) local code, ret = accountDao.getSystemAccount(id)
local state = status.SUCCESS local state = status.SUCCESS
if code ~= 0 then state = status.DATA_IS_WRONG end if code ~= 0 then state = status.DATA_IS_WRONG end
resp: response(state, ret) resp: response(state, ret[1])
end end
--根据账户id获取账户信息 --根据账户id获取账户信息

View File

@ -22,9 +22,10 @@ function _M.getSystemApplications()
ngx.exit(ngx.HTTP_FORBIDDEN) ngx.exit(ngx.HTTP_FORBIDDEN)
end end
--获取页码和请求的数据量 --获取页码和请求的数据量
local pageNum = ngx.var.pagenum or 1 local args = ngx.req.get_uri_args()
local pageSize = ngx.var.pagesize or 10 local pageNum = args["pagenum"] or 1
local code, ret = applicationDao.getSystemApplications() local pageSize = args["pagesize"] or 10
local code, ret = applicationDao.getSystemApplications(pageNum, pageSize)
local state = status.SUCCESS local state = status.SUCCESS
if code ~= 0 then state = status.DATA_IS_WRONG end if code ~= 0 then state = status.DATA_IS_WRONG end
resp: response(state, ret) resp: response(state, ret)
@ -39,10 +40,13 @@ function _M.getSystemApplication(m)
if perm:hasPermission(role, perms) == false then if perm:hasPermission(role, perms) == false then
ngx.exit(ngx.HTTP_FORBIDDEN) ngx.exit(ngx.HTTP_FORBIDDEN)
end end
print("Application id:", m.id)
local code,ret = applicationDao.getSystemApplication(m.id) local code,ret = applicationDao.getSystemApplication(m.id)
local state = status.SUCCESS local state = status.SUCCESS
if code ~= 0 then state = status.DATA_IS_WRONG end if code ~= 0 then state = status.DATA_IS_WRONG end
resp: response(state, ret)
print("Application ret data:", cjson.encode(ret))
resp: response(state, ret[1])
end end
--根据组织id获取应用信息 --根据组织id获取应用信息
@ -57,7 +61,7 @@ function _M.getOrganizationApplication(m)
local code, ret = applicationDao.getOrganizationApplication(m.id) local code, ret = applicationDao.getOrganizationApplication(m.id)
local state = status.SUCCESS local state = status.SUCCESS
if code ~= 0 then state = status.DATA_IS_WRONG end if code ~= 0 then state = status.DATA_IS_WRONG end
resp: response(state, ret) resp: response(state, ret[1])
end end
--根据用户id获取应用的信息 --根据用户id获取应用的信息
@ -72,7 +76,7 @@ function _M.getUserApplication(m)
local code, ret = applicationDao.getUserApplication(m.id) local code, ret = applicationDao.getUserApplication(m.id)
local state = status.SUCCESS local state = status.SUCCESS
if code ~= 0 then state = status.DATA_IS_WRONG end if code ~= 0 then state = status.DATA_IS_WRONG end
resp: response(state, ret) resp: response(state, ret[1])
end end
--根据应用id获取应用信息 --根据应用id获取应用信息

View File

@ -39,7 +39,7 @@ function _M.getSystemDepartment(m)
local code, ret = departmentDao.getSystemDepartment(m.id) local code, ret = departmentDao.getSystemDepartment(m.id)
local state = status.SUCCESS local state = status.SUCCESS
if code ~= 0 then state = status.DATA_IS_WRONG end if code ~= 0 then state = status.DATA_IS_WRONG end
resp: response(state, ret) resp: response(state, ret[1])
end end
--根据组织id添加组织架构信息 --根据组织id添加组织架构信息

View File

@ -120,15 +120,19 @@ function _M.user()
return return
end end
--验证成功获取用户id信息 --验证成功获取用户id信息
local userid = retToken["body"]["payload"]["userid"] local userid = retToken["body"]["payload"]["sub"]
local code, ret = loginDao.getUser(userid) local code, ret = loginDao.getUser(userid)
--读取数据错误 --读取数据错误
if code ~= 0 or table.getn(ret) < 0 then if code ~= 0 or not ret then
resp:response(status.PARAM_TYPE_BIND_ERROR) resp:response(status.PARAM_TYPE_BIND_ERROR)
return return
end end
if #ret <= 0 then
resp:response(status.SUCCESS, nil)
return
end
--返回登陆的用户信息 --返回登陆的用户信息
resp:response(status.SUCCESS, ret) resp:response(status.SUCCESS, ret[1])
end end
--根据token获取用户登录权限 --根据token获取用户登录权限
@ -151,7 +155,7 @@ function _M.permission()
--通过用户id查询到用户的权限信息 --通过用户id查询到用户的权限信息
local code, ret = loginDao.getUser(userid) local code, ret = loginDao.getUser(userid)
--读取数据错误 --读取数据错误
if code ~= 0 or table.getn(ret) < 0 then if code ~= 0 then
resp:response(status.PERMISSION_UNAUTHORISE) resp:response(status.PERMISSION_UNAUTHORISE)
return return
end end

View File

@ -42,7 +42,7 @@ function _M.get_permission(m)
local code,ret = permissionDao.getPermission(m.id) local code,ret = permissionDao.getPermission(m.id)
local state = status.SUCCESS local state = status.SUCCESS
if code ~= 0 then state = status.DATA_IS_WRONG end if code ~= 0 then state = status.DATA_IS_WRONG end
resp: response(state, ret) resp: response(state, ret[1])
end end
--根据角色id获取使用的权限 --根据角色id获取使用的权限
@ -57,7 +57,7 @@ function _M.getSystemPermissionByRole(m)
local code,ret = dao.getPermissionByRole(m.id) local code,ret = dao.getPermissionByRole(m.id)
local state = status.SUCCESS local state = status.SUCCESS
if code ~= 0 then state = status.DATA_IS_WRONG end if code ~= 0 then state = status.DATA_IS_WRONG end
resp: response(state, ret) resp: response(state, ret[1])
end end
--根据权限id获取账号信息 --根据权限id获取账号信息

View File

@ -42,7 +42,7 @@ function _M.getSystemPosition(m)
local code,ret = positionDao.getSystemPosition(m.id) local code,ret = positionDao.getSystemPosition(m.id)
local state = status.SUCCESS local state = status.SUCCESS
if code ~= 0 then state = status.DATA_IS_WRONG end if code ~= 0 then state = status.DATA_IS_WRONG end
resp: response(state, ret) resp: response(state, ret[1])
end end
--根据岗位id添加岗位信息 --根据岗位id添加岗位信息

View File

@ -43,7 +43,7 @@ function _M.getSystemRole(m)
local code,ret = roleDao.getSystemRole(m.id) local code,ret = roleDao.getSystemRole(m.id)
local state = status.SUCCESS local state = status.SUCCESS
if code ~= 0 then state = status.DATA_IS_WRONG end if code ~= 0 then state = status.DATA_IS_WRONG end
resp: response(state, ret) resp: response(state, ret[1])
end end
--根据角色id获取角色信息 --根据角色id获取角色信息

View File

@ -42,9 +42,9 @@ function _M.getSystemUsers(m)
ngx.exit(ngx.HTTP_FORBIDDEN) ngx.exit(ngx.HTTP_FORBIDDEN)
end end
--获取页码和请求的数据量 --获取页码和请求的数据量
--local args = ngx.req.get_uri_args() local args = ngx.req.get_uri_args()
local pageNum = ngx.var.pagenum or 1 local pageNum = args["pagenum"] or 1
local pageSize = ngx.var.pagesize or 10 local pageSize = args["pagesize"] or 10
local code, ret = userDao.getSystemUsers(pageNum, pageSize) local code, ret = userDao.getSystemUsers(pageNum, pageSize)
local state = status.SUCCESS local state = status.SUCCESS
if code ~= 0 then state = status.DATA_IS_WRONG end if code ~= 0 then state = status.DATA_IS_WRONG end
@ -72,7 +72,7 @@ function _M.getSystemUser(m)
local code, ret = userDao.getSystemUser(m.id) local code, ret = userDao.getSystemUser(m.id)
local state = status.SUCCESS local state = status.SUCCESS
if code ~= 0 then state = status.DATA_IS_WRONG end if code ~= 0 then state = status.DATA_IS_WRONG end
resp:response(state, ret) resp:response(state, ret[1])
end end
--根据用户id获取用户信息 --根据用户id获取用户信息

View File

@ -3,23 +3,162 @@
--- Created by admin. --- Created by admin.
--- DateTime: 2025/10/15 09:12 --- DateTime: 2025/10/15 09:12
--- ---
--local snowflake = require("util.snowflake") local snowflake = require("share.snowflake")
local helpers = require("share.helpers") local helpers = require("share.helpers")
local jsonschema = require("jsonschema") local jsonschema = require("jsonschema")
local cjson = require("cjson.safe") local cjson = require("cjson.safe")
local redis = require("share.redis") local redis = require("share.redis")
local jwt = require("resty.jwt") local jwt = require("resty.jwt")
--[[ cjson.encode_number_precision(16)
local workerId = 0 -- 假设当前机器的ID是1范围在[0, 31]之间 local workerId = 0 -- 假设当前机器的ID是1范围在[0, 31]之间
local datacenterId = 0 -- 数据中心ID范围在[0, 31]之间 local datacenterId = 0 -- 数据中心ID范围在[0, 31]之间
local snow = snowflake.new(workerId, datacenterId) local snow = snowflake.new(workerId, datacenterId)
local id = snow:generateUniqueId()-- 生成ID local id = snow:generateUniqueId()-- 生成ID
--ngx.say("Generated ID:"..snow.int64_to_string(id)) --ngx.say("Generated ID:"..snow.int64_to_string(id))
--]]
--max =a and b or c--a?b:c --max =a and b or c--a?b:c
--local socket = require("socket")
local m = require'lualdap'
--[[
if type(m) ~= 'table' then
ngx.say("lualdap is not table")
end
ngx.say(m == package.loaded.lualdap)
ngx.say(m._COPYRIGHT:match'Kepler Project')
ngx.say(m._DESCRIPTION:match'LDAP client')
ngx.say(m._VERSION:match'^LuaLDAP %d%.%d%.%d')
-- luacheck: globals lualdap
if _VERSION == 'Lua 5.1' then
ngx.say("lualdap == m:", lualdap == m)
end
if not os.getenv('OS') then
ngx.say("initialize:", type(m.initialize) == 'function')
end
ngx.say("open function:", type(m.open) == 'function')
ngx.say("open_simple function:", type(m.open_simple) == 'function')
ngx.say('PASS')
--]]
--[[
-- 配置 LDAP 连接参数
local url = "ldap://192.168.0.206:389" --LDAP 服务器地址 + 端口 默认为389
local host = "192.168.0.206" -- LDAP 服务器地址
local port = 389 -- LDAP 端口,通常是 389不加密或 636SSL
local bind_dn = "cn=admin,dc=example,dc=com" -- 认证的账号
local base_dn = "dc=example,dc=com" -- 搜索基准 DN 用户数据存储的根节点
local filter = "uid=username" -- 搜索过滤器
local password = "secret" -- 绑定密码(绑定 DN 对应的密码)
local attrs = {"uid", "mail", "cn"} -- 要检索的属性列表
local scope = m.SCOPE_SUB -- 搜索范围,这里使用子树范围
local object_class = "inetOrgPerson" -- 用户对象类
-- LDAP 过滤条件转义(防注入)
local function escape_ldap_filter(str)
if not str then return "" end
-- 转义 LDAP 特殊字符:( ) & | * \
return str:gsub("([()&|*\\])", "\\%1")
end
-- 参数query_params可选- {uid: "xxx", email: "xxx"} 用于精准查询
local function query_ldap_users(query_params)
-- 创建 LDAP 连接
--方法1
--local ld, err = lualdap.initialize(url)
--local ldap_conn, err = ld:bind_simple(bind_dn, password)
--方法2
local ldap_conn, err = lualdap.open_simple(host, bind_dn, password)
--方法3
--local ldap_conn, err = lualdap.open_simple(url, bind_dn, password)
if not ldap_conn then
ngx.say("LDAP 连接失败:" .. err)
return
end
--构造搜索过滤条件(支持精准查询/模糊查询)
local filter = "(objectClass=" .. object_class .. ")" -- 基础条件:仅查询用户
if query_params then
local conditions = {filter}
-- 按 UID 精准查询(如 uid=zhangsan
if query_params.uid then
table.insert(conditions, "(uid=" .. escape_ldap_filter(query_params.uid) .. ")")
end
-- 按邮箱精准查询(如 mail=zhangsan@company.com
if query_params.email then
table.insert(conditions, "(mail=" .. escape_ldap_filter(query_params.email) .. ")")
end
-- 多条件组合:& 表示“并且”
filter = "(&" .. table.concat(conditions, "") .. ")"
end
ngx.log(ngx.INFO, "LDAP 搜索过滤条件:", filter)
-- 配置搜索参数(指定返回属性)
local search_opts = {
base = base_dn,
scope = "subtree", -- 递归搜索子节点
filter = filter--,
-- 指定返回的属性(按需调整,减少冗余)
--attributes = {"uid", "cn", "sn", "givenName", "mail", "telephoneNumber", "ou", "dn"}
}
-- 执行搜索lualdap 1.4 直接返回用户数组)
local search_iter, err = ldap_conn:search(search_opts)
if not search_iter then
ldap_conn:close()
ngx.say("LDAP 搜索失败:" .. err)
end
--判断返回值类型,自动适配(数组/迭代器)
local res_type = type(search_iter)
ngx.log(ngx.INFO, "lualdap search 返回类型:", res_type) -- 打印类型,方便排查
local ldap_users = {}
while true do
local dn, entry = search_iter() -- 迭代器仅返回 DN 字符串
if not dn then break end
local user_data = {dn = dn}
if entry and type(entry) == "table" then
--for key, value in pairs(entry) do
-- ngx.say("key:", key, " value:", value)
--end
---- 映射属性(属性值是数组,取第一个元素)
user_data.uid = entry.uid
user_data.full_name = entry.cn
user_data.last_name = entry.snWWW
user_data.first_name = entry.givenName
user_data.email = entry.mail
user_data.phone = entry.telephoneNumber
user_data.department = entry.ou
else
ngx.log(ngx.WARN, "用户 ", dn, " 无属性数据")
end
table.insert(ldap_users, user_data)
end
-- 关闭 LDAP 连接(必须执行,释放资源)
ldap_conn:close()
return ldap_users
end
local query_params = {
uid = ngx.var.arg_uid,
email = ngx.var.arg_email
}
--query_params.uid = "Michael"
local res = query_ldap_users(query_params)
ngx.header["Content-Type"] = "json"
ngx.say(cjson.encode(res))
do return end
--]]
--[[
local STATUS_CODE = { local STATUS_CODE = {
-- 成功状态码 -- 成功状态码
SUCCESS = { code = 200, message = "操作成功" }, SUCCESS = { code = 200, message = "操作成功" },
@ -38,6 +177,7 @@ if not ok then
end end
ngx.say("Lua-GD version: " .. gd.VERSION) ngx.say("Lua-GD version: " .. gd.VERSION)
ngx.say("Lua-GD features:") ngx.say("Lua-GD features:")
--]]
--[[ --[[
local iSeed = os.time() + os.clock() * 10000 local iSeed = os.time() + os.clock() * 10000
@ -71,10 +211,6 @@ print("")
io.write(im:pngStr()) io.write(im:pngStr())
--]] --]]
local uuid = require("util.uuid")
local uid = uuid.generateUuid()
ngx.say("uuid:"..uid)
--[[ --[[
local genpic = require("util.generatechaptcha") local genpic = require("util.generatechaptcha")
local filename, fp = genpic.getChaptcha() local filename, fp = genpic.getChaptcha()
@ -113,6 +249,7 @@ local openssl = require "resty.openssl"
local digest = require "resty.openssl.digest" local digest = require "resty.openssl.digest"
local pkey = require "resty.openssl.pkey" local pkey = require "resty.openssl.pkey"
local str = require "resty.string" local str = require "resty.string"
local bn = require "resty.openssl.bn" -- 导入 bn 大整数模块
local x509 = require "resty.openssl.x509" local x509 = require "resty.openssl.x509"
local x509_name = require "resty.openssl.x509.name" local x509_name = require "resty.openssl.x509.name"
@ -546,8 +683,8 @@ ngx.say("JWT is valid: ", cjson.encode(decoded))
-- 1. 生成 RSA 私钥2048 位,可改为 4096 提升安全性) -- 1. 生成 RSA 私钥2048 位,可改为 4096 提升安全性)
local priv_key, err = pkey.new({ local priv_key, err = pkey.new({
type = "RSA", -- 密钥类型RSA/ECC type = pkey.RSA, -- 指定算法为 RSA
bits = 2048, -- 密钥长度 bits = 2048, -- 私钥长度 2048 位
-- 可选ECC 密钥配置(替换 RSA 时使用) -- 可选ECC 密钥配置(替换 RSA 时使用)
-- type = "EC", -- type = "EC",
-- curve = "prime256v1", -- P-256 曲线 -- curve = "prime256v1", -- P-256 曲线
@ -598,21 +735,43 @@ end
ok, err = cert:set_version(3) -- 版本号从 0 开始3 对应 X509v3 ok, err = cert:set_version(3) -- 版本号从 0 开始3 对应 X509v3
if not ok then error(err) end if not ok then error(err) end
-- 设置序列号(唯一标识,建议用随机数避免冲突) -- 2. 生成随机序列号Lua number 类型)
math.randomseed(os.time()) local timestamp = tostring(os.time()) -- 时间戳保证唯一性
local serial = math.random(1000000000, 9999999999) local random_str = tostring(math.random(1000000000, 9999999999)) -- 10 位随机数
print("serial value:", serial) local serial_num = timestamp .. random_str -- 拼接为 20 位纯数字字符串
ok, err = cert:set_serial_number(serial)
if not ok then error(err) end
-- 设置有效期起始时间当前时间结束时间365 天后) -- 3. 核心修正:将 number 转为 bn 大整数对象(优先用字符串传入,避免大数溢出)
local not_before = os.date("*t") local serial_bn, bn_err = bn.new(tostring(serial_num))
local not_after = os.date("*t") if not serial_bn then
not_after.year = not_after.year + 1 -- 有效期 1 年 error("failed to create bn object for serial: " .. (bn_err or "unknown error"))
ok, err = cert:set_not_before(not_before) end
if not ok then error(err) end print("serial value (bn object):", serial_bn)
ok, err = cert:set_not_after(not_after)
if not ok then error(err) end -- 4. 调用 set_serial_number传入 bn 对象(不再报错)
local ok, err = cert:set_serial_number(serial_bn)
if not ok then
error("failed to set serial number: " .. (err or "unknown error"))
end
-- 1. 获取当前时间的 Unix 时间戳(数字类型,直接可用)
local not_before_ts = os.time() -- 无需 os.date("*t"),直接返回数字
print("证书生效时间戳:", not_before_ts)
-- 2. 计算 1 年后的时间戳(先转表修改,再转回时间戳)
local not_after_tab = os.date("*t") -- 获取时间表
not_after_tab.year = not_after_tab.year + 1 -- 有效期 1 年
local not_after_ts = os.time(not_after_tab) -- 将修改后的时间表转为 Unix 时间戳
print("证书过期时间戳:", not_after_ts)
-- 3. 调用 set_not_before/set_not_after传入数字类型时间戳无报错
local ok1, err1 = cert:set_not_before(not_before_ts)
if not ok1 then
return nil, "设置证书生效时间失败: " .. (err1 or "未知错误")
end
local ok2, err2 = cert:set_not_after(not_after_ts)
if not ok2 then
return nil, "设置证书过期时间失败: " .. (err2 or "未知错误")
end
-- 设置证书主体和颁发者(自签名:主体 = 颁发者) -- 设置证书主体和颁发者(自签名:主体 = 颁发者)
ok, err = cert:set_subject_name(dn) ok, err = cert:set_subject_name(dn)
@ -620,11 +779,17 @@ if not ok then error(err) end
ok, err = cert:set_issuer_name(dn) ok, err = cert:set_issuer_name(dn)
if not ok then error(err) end if not ok then error(err) end
-- 绑定公钥(从私钥中提取) -- 绑定公钥(从私钥中提取)使用 get_public() 提取公钥(而非 get_public_key()
local pub_key, err = priv_key:get_public_key() local pub_key, err = priv_key:to_PEM("public")
if not pub_key then error("提取公钥失败: " .. err) end if not pub_key then error("提取公钥失败: " .. err) end
ok, err = cert:set_pubkey(pub_key) local pkey_obj, err = pkey.new(pub_key)
if not ok then error(err) end if not pkey_obj then
return nil, "创建公钥实例失败:" .. (err or "未知错误")
end
ok, err = cert:set_pubkey(pkey_obj)
if not ok then
return nil, "绑定证书公钥失败:" .. (err or "未知错误")
end
-- 4. 配置证书扩展属性(关键!否则证书可能无法被浏览器/客户端信任) -- 4. 配置证书扩展属性(关键!否则证书可能无法被浏览器/客户端信任)
-- 4.1 基本约束(自签名证书设为 CA:FALSE -- 4.1 基本约束(自签名证书设为 CA:FALSE

View File

@ -45,9 +45,9 @@ function _M.consume(code, client_id)
if data == nil then if data == nil then
return nil, "无效的授权码" return nil, "无效的授权码"
end end
--
-- 消费后立即删除(一次性) ---- 消费后立即删除(一次性)
shared_dict:delete(code_key) --shared_dict:delete(code_key)
local code_data = cjson.decode(data) local code_data = cjson.decode(data)
--[[ --[[

View File

@ -28,6 +28,7 @@ function _M.validate(client_id, redirect_uri)
end end
local client = cjson.decode(client_str) local client = cjson.decode(client_str)
--[[
-- 验证 redirect_uri 是否在客户端注册的范围内 -- 验证 redirect_uri 是否在客户端注册的范围内
local valid_redirect = false local valid_redirect = false
for _, uri in ipairs(client.redirect_uris) do for _, uri in ipairs(client.redirect_uris) do
@ -39,6 +40,7 @@ function _M.validate(client_id, redirect_uri)
if not valid_redirect then if not valid_redirect then
return nil, "无效的 redirect_uri" return nil, "无效的 redirect_uri"
end end
--]]
return client return client
end end

View File

@ -1,4 +1,5 @@
local cjson = require('cjson') local cjson = require('cjson')
cjson.encode_empty_table_as_object(false) -- 空表编码为数组
local STATUS = require('util.status') local STATUS = require('util.status')
local _M = {} local _M = {}
@ -13,7 +14,7 @@ function _M:json(state, message, data, http_status)
msg = status.message msg = status.message
end end
local response = { code = code, msg = msg, result = data, timestamp = ngx.time() } local response = { code = code, msg = msg, result = data, timestamp = ngx.time() }
print("response:", cjson.encode(response)) print("json data:", cjson.encode(data))
return { return {
code = response_status, code = response_status,
headers = { content_type = 'application/json; charset=UTF-8' }, headers = { content_type = 'application/json; charset=UTF-8' },
@ -28,7 +29,7 @@ function _M:json(state, data, http_status)
local msg = status.message local msg = status.message
local response_status = http_status or ngx.HTTP_OK local response_status = http_status or ngx.HTTP_OK
local response = { code = code, msg = msg, result = data,timestamp = ngx.time() } local response = { code = code, msg = msg, result = data,timestamp = ngx.time() }
--print("response:", cjson.encode(response)) print("json -- data:", cjson.encode(data))
return { return {
code = response_status, code = response_status,
headers = { content_type = 'application/json; charset=UTF-8' }, headers = { content_type = 'application/json; charset=UTF-8' },

View File

@ -42,6 +42,8 @@ function _M.generateToken(userid, username, role_id, role_name)
obj.payload.username = username obj.payload.username = username
obj.payload.role_id = role_id obj.payload.role_id = role_id
obj.payload.role_name = role_name obj.payload.role_name = role_name
obj.payload.exp = ngx.time() + conf.access_token_ttl * 6 -- 过期时间(例如:当前时间+1小时
obj.payload.iat = ngx.time() -- 签发时间
--获取的登陆的用户信息返回tocken --获取的登陆的用户信息返回tocken
local jwt_token = jwt:sign(conf.secret_key, obj) local jwt_token = jwt:sign(conf.secret_key, obj)
return "Bearer "..jwt_token return "Bearer "..jwt_token

View File

@ -18,13 +18,14 @@ local schema = {
favicon = { type = "string" }, favicon = { type = "string" },
description = { type = "string" }, description = { type = "string" },
homepage_url = { type = "string" }, homepage_url = { type = "string" },
redirect_uris = { type = "string" }, redirect_uri = { type = "string" },
}, },
required = { "name", "redirect_uris" } required = { "name", "redirect_uri" }
} }
function _M.validateJson(jsonData) function _M.validateJson(jsonData)
-- 验证数据是否符合schema -- 验证数据是否符合schema
print("jsondata:", jsonData)
local validator = jsonschema.generate_validator(schema) local validator = jsonschema.generate_validator(schema)
local result = validator(jsonData) local result = validator(jsonData)
return result return result