Compare commits

...

14 Commits

Author SHA1 Message Date
7c8a9452f2 应用程序增加通过客户端id和重定向地址查询是否存在函数,oauth增加authorize认证流程,有待测试 2025-11-12 21:53:53 +08:00
0508599f34 用户登录业务逻辑,接收前端用户名从数据表中获取数据,然后取出密码进行md5加密,再与前端传的密码进行比对,相等则进入系统 2025-11-12 15:27:52 +08:00
wanglei
ece64e90f3 修改前端访问接口时允许跨站访问 2025-11-12 15:07:47 +08:00
wanglei
e8fe6be8de 用户登录进行json验证对其进行修改 2025-11-12 14:41:58 +08:00
8c9015fe06 修改jsonschema校验json数据是否为空等错误信息结构修改 2025-11-12 10:38:29 +08:00
wanglei
697762157e 暂时先注释掉权限管理验证,修改组织结构不使用分页进行数据返回 2025-11-12 09:58:02 +08:00
bdf2d82a37 对接口正确返回正确结果200 2025-11-12 09:41:22 +08:00
wanglei
c41075f2b5 修改接口的url路由,并修改文件中报错问题 2025-11-12 09:36:00 +08:00
953e805a6b 修改jsonshema验证数据的例子,增加共享字典删除共享字典中的键值 2025-11-11 23:39:44 +08:00
wanglei
2c525e1f61 修改oauth登录后返回code,并将code存储到共享字典中,设置有效时间进行自动删除 2025-11-11 21:35:21 +08:00
wanglei
242391f577 对例子进行openssl进行签名验证进行问题修改 2025-11-11 19:51:35 +08:00
wanglei
e422654320 修改openssl进行验签功能错误的问题 2025-11-11 19:26:53 +08:00
wanglei
abb59406ee 增加oauth2.0相关协议接口,并对配置文件进行修改,增加公钥和私钥生成相关函数和使用的测试例子 2025-11-11 19:00:22 +08:00
e62ba6a9d7 添加生成密钥和公钥的例子 2025-11-10 20:05:52 +08:00
37 changed files with 1143 additions and 330 deletions

View File

@ -25,8 +25,8 @@ http {
#lua_ssl_verify_depth 3;
#在Nginx启动时执行的Lua代码块
#初始化用户角色权限相关的共享内存
lua_shared_dict dict 10m;
#oauth2.0第三方验证后将code放到共享内存中
lua_shared_dict codeDict 5m;
#init_by_lua_block {
# -- 定义一个全局变量
# ngx.log(ngx.INFO, "Initializing global variable")
@ -53,12 +53,15 @@ http {
set $APP_PATH '/home/frankly/work/AuthPlatform';
#访问时允许跨域处理
access_by_lua_block {
ngx.header["Access-Control-Allow-Origin"] = "*"
ngx.header["Access-Control-Allow-Methods"] = "GET, POST, DELETE, PUT"
ngx.header["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
access_by_lua_block {
ngx.header["Access-Control-Allow-Origin"] = "*";
ngx.header["Access-Control-Allow-Methods"] = "GET, POST, DELETE, PUT";
ngx.header["Access-Control-Allow-Headers"] = "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";
ngx.header["Access-Control-Max-Age"] = 1728000;
ngx.header["Access-Control-Expose-Headers"] = "Content-Length,Content-Range";
if ngx.var.request_method == "OPTIONS" then
ngx.exit(ngx.HTTP_NOT_ALLOWED)
ngx.status = 204
ngx.exit(ngx.OK)
end
}

View File

@ -2,48 +2,56 @@
### 接口相关控制接口文件需要使用jwt进行token验证 ###
######################################################
#用户认证登陆相关
location /api/user {
location /yum/v1/system/user {
content_by_lua_file '${APP_PATH}/src/api/system/login.lua';
}
#账号信息数据接口
location /api/system/accounts {
location /yum/v1/system/accounts {
access_by_lua_file '${APP_PATH}/src/auth/jwt-auth.lua';
content_by_lua_file '${APP_PATH}/src/api/system/account.lua';
}
#应用程序信息数据接口
location /api/system/applications {
location /yum/v1/system/applications {
access_by_lua_file '${APP_PATH}/src/auth/jwt-auth.lua';
content_by_lua_file '${APP_PATH}/src/api/system/application.lua';
}
#组织(岗位)信息数据接口
location /api/system/departments {
location /yum/v1/system/departments {
access_by_lua_file '${APP_PATH}/src/auth/jwt-auth.lua';
content_by_lua_file '${APP_PATH}/src/api/system/department.lua';
}
#权限信息数据接口
location /api/system/permissions {
location /yum/v1/system/permissions {
access_by_lua_file '${APP_PATH}/src/auth/jwt-auth.lua';
content_by_lua_file '${APP_PATH}/src/api/system/permission.lua';
}
#岗位信息数据接口
location /api/system/positions {
location /yum/v1/system/positions {
access_by_lua_file '${APP_PATH}/src/auth/jwt-auth.lua';
content_by_lua_file '${APP_PATH}/src/api/system/position.lua';
}
#账号信息数据接口
location /api/system/roles {
location /yum/v1/system/roles {
access_by_lua_file '${APP_PATH}/src/auth/jwt-auth.lua';
content_by_lua_file '${APP_PATH}/src/api/system/role.lua';
}
#用户信息数据接口
location /api/system/users {
location /yum/v1/system/users {
access_by_lua_file '${APP_PATH}/src/auth/jwt-auth.lua';
content_by_lua_file '${APP_PATH}/src/api/system/user.lua';
}
######################################################
### oauth2.0 + openIDC 接口文件处理 ###
######################################################
#用户认证登陆相关
location /yum/v1/oauth/v2 {
content_by_lua_file '${APP_PATH}/src/api/oauth/oauth.lua';
}

View File

@ -11,41 +11,47 @@ local oauthService = require("service.oauth.oauth")
--定义相关路由前端接口url地址
local routes = {
--------------------------------------------
-------------OAuth2.0认证相关路由配置--------------
------------ OAuth2.0认证相关路由配置 ---------
--------------------------------------------
--获取授权码
{
paths = { "/api/oauth/v2/authorize" },
paths = { "/yum/v1/oauth/v2/authorize" },
methods = { "POST" },
handler = oauthService.authorize,
},
--根据授权码获取Access-Token
{
paths = { "/api/oauth/v2/token" },
paths = { "/yum/v1/oauth/v2/token" },
methods = { "POST" },
handler = oauthService.token,
},
--通过用户名和密码进行验证
{
paths = { "/yum/v1/oauth/v2/login" },
methods = { "POST" },
handler = oauthService.login,
},
--根据Access-Token获取相应用户的账户信息
{
paths = { "/api/oauth/v2/userinfo" },
paths = { "/yum/v1/oauth/v2/userinfo" },
methods = { "POST" },
handler = oauthService.userinfo,
},
--回收Access-Token
{
paths = { "/api/oauth/v2/logout" },
paths = { "/yum/v1/oauth/v2/logout" },
methods = { "POST" },
handler = oauthService.logout,
},
--根据Refresh-Token刷新Access-Token
{
paths = { "/api/oauth/v2/refresh" },
paths = { "/yum/v1/oauth/v2/refresh" },
methods = { "POST" },
handler = oauthService.refresh,
},
--验证token是否有效
{
paths = { "/api/oauth/v2/checklogin" },
paths = { "/yum/v1/oauth/v2/checklogin" },
methods = { "POST" },
handler = oauthService.checklogin,
},

View File

@ -13,7 +13,7 @@ local systemAccount = require("service.system.account")
local routes = {
--账户相关路由接口
{
paths = { "/api/system/accounts" },
paths = { "/yum/v1/system/accounts" },
methods = { "GET" },
filter_fun = function(vars)
ngx.ctx.perms = "system::accounts::list"
@ -22,7 +22,7 @@ local routes = {
handler = systemAccount.getSystemAccounts,
},
{
paths = { "/api/system/accounts/:id" },
paths = { "/yum/v1/system/accounts/:id" },
methods = { "GET" },
filter_fun = function(vars)
ngx.ctx.perms = "system::accounts::view"
@ -31,7 +31,7 @@ local routes = {
handler = systemAccount.getSystemAccount,
},
{
paths = { "/api/system/accounts" },
paths = { "/yum/v1/system/accounts" },
methods = { "POST" },
filter_fun = function(vars)
ngx.ctx.perms = "system::accounts::add"
@ -40,7 +40,7 @@ local routes = {
handler = systemAccount.addSystemAccount,
},
{
paths = { "/api/system/accounts/:id" },
paths = { "/yum/v1/system/accounts/:id" },
methods = { "DELETE" },
filter_fun = function(vars)
ngx.ctx.perms = "system::accounts::delete"
@ -49,7 +49,7 @@ local routes = {
handler = systemAccount.deleteSystemAccount,
},
{
paths = { "/api/system/accounts/:id" },
paths = { "/yum/v1/system/accounts/:id" },
methods = { "PUT" },
filter_fun = function(vars)
ngx.ctx.perms = "system::accounts::edit"

View File

@ -13,7 +13,7 @@ local systemApplication = require("service.system.application")
local routes = {
--应用相关路由接口
{
paths = { "/api/system/applications" },
paths = { "/yum/v1/system/applications" },
methods = { "GET" },
filter_fun = function(vars)
ngx.ctx.perms = "system::applications::list"
@ -22,7 +22,7 @@ local routes = {
handler = systemApplication.getSystemApplications,
},
{
paths = { "/api/system/applications/:id" },
paths = { "/yum/v1/system/applications/:id" },
methods = { "GET" },
filter_fun = function(vars)
ngx.ctx.perms = "system::applications::view"
@ -31,7 +31,7 @@ local routes = {
handler = systemApplication.getSystemApplication,
},
{
paths = { "/api/system/applications" },
paths = { "/yum/v1/system/applications" },
methods = { "POST" },
filter_fun = function(vars)
ngx.ctx.perms = "system::applications::add"
@ -40,7 +40,7 @@ local routes = {
handler = systemApplication.addSystemApplication,
},
{
paths = { "/api/system/applications/:id" },
paths = { "/yum/v1/system/applications/:id" },
methods = { "DELETE" },
filter_fun = function(vars)
ngx.ctx.perms = "system::applications::delete"
@ -49,7 +49,7 @@ local routes = {
handler = systemApplication.deleteSystemApplication,
},
{
paths = { "/api/system/applications/:id" },
paths = { "/yum/v1/system/applications/:id" },
methods = { "PUT" },
filter_fun = function(vars)
ngx.ctx.perms = "system::applications::edit"

View File

@ -13,7 +13,7 @@ local systemDepartment = require("service.system.department")
local routes = {
--组织(部门)相关路由接口
{
paths = { "/api/system/departments" },
paths = { "/yum/v1/system/departments" },
methods = { "GET" },
filter_fun = function(vars)
ngx.ctx.perms = "system::departments::list"
@ -22,7 +22,7 @@ local routes = {
handler = systemDepartment.getSystemDepartments,
},
{
paths = { "/api/system/departments/:id" },
paths = { "/yum/v1/system/departments/:id" },
methods = { "GET" },
filter_fun = function(vars)
ngx.ctx.perms = "system::departments::view"
@ -31,7 +31,7 @@ local routes = {
handler = systemDepartment.getSystemDepartment,
},
{
paths = { "/api/system/departments" },
paths = { "/yum/v1/system/departments" },
methods = { "POST" },
filter_fun = function(vars)
ngx.ctx.perms = "system::departments::add"
@ -40,7 +40,7 @@ local routes = {
handler = systemDepartment.addSystemDepartment,
},
{
paths = { "/api/system/departments/:id" },
paths = { "/yum/v1/system/departments/:id" },
methods = { "DELETE" },
filter_fun = function(vars)
ngx.ctx.perms = "system::departments::delete"
@ -49,7 +49,7 @@ local routes = {
handler = systemDepartment.deleteSystemDepartment,
},
{
paths = { "/api/system/departments/:id" },
paths = { "/yum/v1/system/departments/:id" },
methods = { "PUT" },
filter_fun = function(vars)
ngx.ctx.perms = "system::departments::edit"

View File

@ -15,31 +15,31 @@ local routes = {
--------------------------------------------
--用户登录路由接口
{
paths = { "/api/user/login" },
paths = { "/yum/v1/system/user/login" },
methods = { "POST" },
handler = loginService.login,
},
--用户注册路由接口
{
paths = { "/api/user/signup" },
paths = { "/yum/v1/system/user/signup" },
methods = { "POST" },
handler = loginService.signup,
},
--用户退出路由接口
{
paths = { "/api/user/logout" },
paths = { "/yum/v1/system/user/logout" },
methods = { "POST" },
handler = loginService.logout,
},
--根据token信息获取用户信息数据
{
paths = { "/api/user/user" },
paths = { "/yum/v1/system/user/user" },
methods = { "GET" },
handler = loginService.user,
},
--根据token信息获取用户权限数据
{
paths = { "/api/user/permission" },
paths = { "/yum/v1/system/user/permission" },
methods = { "GET" },
handler = loginService.permission,
},

View File

@ -13,7 +13,7 @@ local systemPermission = require("service.system.permission")
local routes = {
--权限相关路由接口
{
paths = { "/api/system/permissions" },
paths = { "/yum/v1/system/permissions" },
methods = { "GET" },
filter_fun = function(vars)
ngx.ctx.perms = "system::permissions::list"
@ -22,7 +22,7 @@ local routes = {
handler = systemPermission.getSystemPermissions,
},
{
paths = { "/api/system/permissions/:id" },
paths = { "/yum/v1/system/permissions/:id" },
methods = { "GET" },
filter_fun = function(vars)
ngx.ctx.perms = "system::permissions::view"
@ -31,7 +31,7 @@ local routes = {
handler = systemPermission.getSystemPermission,
},
{
paths = { "/api/system/permissions" },
paths = { "/yum/v1/system/permissions" },
methods = { "POST" },
filter_fun = function(vars)
ngx.ctx.perms = "system::permissions::add"
@ -40,7 +40,7 @@ local routes = {
handler = systemPermission.addSystemPermission,
},
{
paths = { "/api/system/permissions/:id" },
paths = { "/yum/v1/system/permissions/:id" },
methods = { "DELETE" },
filter_fun = function(vars)
ngx.ctx.perms = "system::permissions::delete"
@ -49,7 +49,7 @@ local routes = {
handler = systemPermission.deleteSystemPermission,
},
{
paths = { "/api/system/permissions/:id" },
paths = { "/yum/v1/system/permissions/:id" },
methods = { "PUT" },
filter_fun = function(vars)
ngx.ctx.perms = "system::permissions::edit"

View File

@ -13,7 +13,7 @@ local systemPosition = require("service.system.position")
local routes = {
--岗位相关路由接口
{
paths = { "/api/system/positions" },
paths = { "/yum/v1/system/positions" },
methods = { "GET" },
filter_fun = function(vars)
ngx.ctx.perms = "system::positions::list"
@ -22,7 +22,7 @@ local routes = {
handler = systemPosition.getSystemPositions,
},
{
paths = { "/api/system/positions/:id" },
paths = { "/yum/v1/system/positions/:id" },
methods = { "GET" },
filter_fun = function(vars)
ngx.ctx.perms = "system::positions::view"
@ -31,7 +31,7 @@ local routes = {
handler = systemPosition.getSystemPosition,
},
{
paths = { "/api/system/positions" },
paths = { "/yum/v1/system/positions" },
methods = { "POST" },
filter_fun = function(vars)
ngx.ctx.perms = "system::positions::add"
@ -40,7 +40,7 @@ local routes = {
handler = systemPosition.addSystemPosition,
},
{
paths = { "/api/system/positions/:id" },
paths = { "/yum/v1/system/positions/:id" },
methods = { "DELETE" },
filter_fun = function(vars)
ngx.ctx.perms = "system::positions::delete"
@ -49,7 +49,7 @@ local routes = {
handler = systemPosition.deleteSystemPosition,
},
{
paths = { "/api/system/positions/:id" },
paths = { "/yum/v1/system/positions/:id" },
methods = { "PUT" },
filter_fun = function(vars)
ngx.ctx.perms = "system::positions::edit"

View File

@ -13,7 +13,7 @@ local systemRole = require("service.system.role")
local routes = {
--角色相关路由接口
{
paths = { "/api/system/roles" },
paths = { "/yum/v1/system/roles" },
methods = { "GET" },
filter_fun = function(vars)
ngx.ctx.perms = "system::roles::list"
@ -22,7 +22,7 @@ local routes = {
handler = systemRole.getSystemRoles,
},
{
paths = { "/api/system/roles/:id" },
paths = { "/yum/v1/system/roles/:id" },
methods = { "GET" },
filter_fun = function(vars)
ngx.ctx.perms = "system::roles::view"
@ -31,7 +31,7 @@ local routes = {
handler = systemRole.getSystemRole,
},
{
paths = { "/api/system/roles" },
paths = { "/yum/v1/system/roles" },
methods = { "POST" },
filter_fun = function(vars)
ngx.ctx.perms = "system::roles::add"
@ -40,7 +40,7 @@ local routes = {
handler = systemRole.addSystemRole,
},
{
paths = { "/api/system/roles/:id" },
paths = { "/yum/v1/system/roles/:id" },
methods = { "DELETE" },
filter_fun = function(vars)
ngx.ctx.perms = "system::roles::delete"
@ -49,7 +49,7 @@ local routes = {
handler = systemRole.deleteSystemRole,
},
{
paths = { "/api/system/roles/:id" },
paths = { "/yum/v1/system/roles/:id" },
methods = { "PUT" },
filter_fun = function(vars)
ngx.ctx.perms = "system::roles::edit"

View File

@ -13,7 +13,7 @@ local routes = {
--用户相关路由接口
--获取所有用户信息数据
{
paths = { "/api/system/users" },
paths = { "/yum/v1/system/users" },
methods = { "GET" },
filter_fun = function(vars)
ngx.ctx.perms = "system::users::list"
@ -23,7 +23,7 @@ local routes = {
},
--根据用户id获取用户详情信息
{
paths = { "/api/system/users/:id" },
paths = { "/yum/v1/system/users/:id" },
methods = { "GET" },
filter_fun = function(vars)
ngx.ctx.perms = "system::users::view"
@ -33,7 +33,7 @@ local routes = {
},
--根据增加新的用户信息
{
paths = { "/api/system/users" },
paths = { "/yum/v1/system/users" },
methods = { "POST" },
filter_fun = function(vars)
ngx.ctx.perms = "system::users::add"
@ -43,7 +43,7 @@ local routes = {
},
--根据用户id删除用户信息
{
paths = { "/api/system/users/:id" },
paths = { "/yum/v1/system/users/:id" },
methods = { "DELETE" },
filter_fun = function(vars)
ngx.ctx.perms = "system::users::delete"
@ -53,7 +53,7 @@ local routes = {
},
--根据用户id编辑用户信息
{
paths = { "/api/system/users/:id" },
paths = { "/yum/v1/system/users/:id" },
methods = { "PUT" },
filter_fun = function(vars)
ngx.ctx.perms = "system::users::edit"

View File

@ -53,7 +53,7 @@ end
-- write the uid variable
ngx.ctx.userid = jwt_obj.payload.userid
ngx.ctx.username = jwt_obj.payload.username
ngx.ctx.role = jwt_obj.payload.role
ngx.ctx.role = jwt_obj.payload.role_name
ngx.log(ngx.WARN, "claims: ".. cjson.encode(jwt_obj.payload))
--全部校验完成后,说明令牌有效,返回令牌数据

View File

@ -4,22 +4,10 @@
--- DateTime: 2025/10/29 23:36
---
local userDao = require("dao.system.user")
local applicationDao = require("dao.system.application")
local _M = {}
--认证用户返回用户数据信息
local function authenticate(name, passwd)
--验证用户名是否为空
if name == "" then
return 0x010003, nil
end
--验证密码是否为空
if passwd == "" then
return 0x010002, nil
end
return userDao:adjustUser(name, passwd)
end
--用户登录业务逻辑处理
function _M.login(jsonData)
--解析json中的键和数据值
@ -28,7 +16,7 @@ function _M.login(jsonData)
local captcha = jsonData["captcha"]
local checkKey = jsonData["checkKey"]
--验证用户名是否为空
local code, res = authenticate(name, passwd)
local code, res = userDao:getUserByUsername(name) --authenticate(name, passwd)
if code ~= 0 then
return 0x000001,res
end
@ -36,12 +24,17 @@ function _M.login(jsonData)
if res ~= nil then
num = table.getn(res)
end
--用户存在时返回用户已经存在
--用户存在时返回
if num <= 0 then
return 0x01000C,nil
end
--进行密码验证 获取数据库的密码
local pwdMd5 = ngx.md5(res[1].password)
if pwdMd5 ~= passwd then
return 0x000001,res --密码错误
end
local userid = res[1].id
--获取用户id查询角色信息
--通过用户id获取应用程序id和应用名称
local err, rest = userDao:userRole(userid)
if rest == nil then
return 0x01000C,nil
@ -67,4 +60,8 @@ function _M.getUser(userid)
return userDao:getSystemUser(userid)
end
function _M.getApplicationBy(client_id, redirect_uri)
return applicationDao.getApplicationByClientId(client_id, redirect_uri)
end
return _M

View File

@ -104,4 +104,9 @@ function _M.updateApplication(id, jsonData)
return applicationModel:where('id', '=', id):update(jsonData)
end
--根据客户端id和重定向地址获取应用程序
function _M.getApplicationByClientId(client_id, redirect_uri)
return applicationModel:where('app_id', '=', client_id):where('redirect_uris', '=', redirect_uri):get()
end
return _M

View File

@ -31,8 +31,8 @@ local function isExistDepartment(id)
end
-- 查询数据表中的所有组织架构信息
function _M.getSystemDepartments(pageNum, pageSize)
return departmentModel:paginate(pageNum, pageSize)
function _M.getSystemDepartments()
return departmentModel:all()
end
--根据组织架构id获取组织架构信息

View File

@ -9,17 +9,22 @@ local _M = {}
--认证用户返回用户数据信息
local function authenticate(name, passwd)
--验证用户名是否为空
if name == "" then
--验证用户名或者密码是否为空
if name == "" or passwd == "" then
return 0x010003, nil
end
--验证密码是否为空
if passwd == "" then
return 0x010002, nil
end
return userDao:adjustUser(name, passwd)
end
--根据用户名称获取用户信息
local function getUserByUsername(username)
--验证用户名否为空
if username == "" then
return 0x010003, nil
end
return userDao:getUserByUsername(username)
end
--用户登录业务逻辑处理
function _M.login(jsonData)
--解析json中的键和数据值
@ -28,7 +33,7 @@ function _M.login(jsonData)
local captcha = jsonData["captcha"]
local checkKey = jsonData["checkKey"]
--验证用户名是否为空
local code, res = authenticate(name, passwd)
local code, res = userDao:getUserByUsername(name) --authenticate(name, passwd)
if code ~= 0 then
return 0x000001,res
end
@ -36,10 +41,15 @@ function _M.login(jsonData)
if res ~= nil then
num = table.getn(res)
end
--用户存在时返回用户已经存在
--用户存在时返回
if num <= 0 then
return 0x01000C,nil
end
--进行密码验证 获取数据库的密码
local pwdMd5 = ngx.md5(res[1].password)
if pwdMd5 ~= passwd then
return 0x000001,res --密码错误
end
local userid = res[1].id
--获取用户id查询角色信息
local err, rest = userDao:userRole(userid)

View File

@ -37,6 +37,15 @@ local function isExistUser(id)
return true
end
--通过用户名验证用户是否存在
function _M:getUserByUsername(username)
local code, res = userModel:where("username", "=", username):orwhere("phone", "=", username):orwhere("email", "=", username):get()
if code ~= 0 then
return 0x000001,res
end
return code, res
end
-- 查询数据表中的所有用户信息
function _M.getSystemUsers(pageNum, pageSize)
return userModel:paginate(pageNum, pageSize)
@ -58,7 +67,7 @@ function _M.addSystemUser(jsonData)
local email = jsonData['email']
--根据用户、手机号、邮箱进行验证用户是否存在
local code, res = userModel:where("username", "=", userName):orwhere("phone", "=", phone):orwhere("email", "=", email):get()
local code, res = self.getUserByUsername(userName)
if code ~= 0 then
return 0x000001,res
end
@ -73,9 +82,9 @@ function _M.addSystemUser(jsonData)
--键值为id产生uuid数据值增加到json中
jsonData.id = helpers.getUuid()
--用户密码暂时使用md5进行加密
local pwd = jsonData['password']
jsonData.password = ngx.md5(pwd)
--用户密码暂时使用md5进行加密 使用明文暂时注释掉加密
--local pwd = jsonData['password']
--jsonData.password = ngx.md5(pwd)
-- 创建一个用户
return userModel:create(jsonData)
end
@ -108,7 +117,7 @@ function _M:adjustUser(name, passwd)
if name == nil or passwd == nil then
return 0x010003, nil
end
local pwdMd5 = ngx.md5(passwd)
local pwdMd5 = passwd--ngx.md5(passwd)
--根据用户进行验证用户是否存在
local code, res = userModel:where("username", "=", name):where("password", "=", pwdMd5):get()
if code == 0 and res ~= nil then

View File

@ -8,6 +8,7 @@ local authDao = require("dao.oauth.oauth")
local validator = require("validator.oauth.oauth")
local cjson = require("cjson.safe")
local token = require("util.uuid")
local jwt = require "resty.jwt"
local _M = {}
@ -15,32 +16,273 @@ local _M = {}
function _M:authorize()
--读取请求体的数据
ngx.req.read_body()
local args = ngx.req.get_uri_args()
--获取请求数据
local body_data = ngx.req.get_body_data()
-- 验证数据是否符合json
local ok = validatorJson.validatorAuthorize(body_data)
-- 验证json数据是否正确
local ok, data = pcall(cjson.decode, body_data)
if not ok then
return ngx.exit(ngx.HTTP_BAD_REQUEST)
end
-- 校验客户端请求参数
ok = validator.validatorAuthorize(data)
--验证失败则返回
if not ok then
local result = resp:json(0x000001)
resp:send(result)
return ngx.exit(ngx.HTTP_BAD_REQUEST)
end
-- 校验 response_type 必须为 "code"(授权码模式)
if args.response_type ~= "code" then
return ngx.exit(ngx.HTTP_BAD_REQUEST)
end
-- 校验客户端id和redirect_uri是否存在数据库
local code, res = authDao.getApplicationBy(args.client_id, args.redirect_uri)
if code ~= 0 or not res then
return ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
-- 验证范围
if args.scope then
local requested_scopes = {}
for scope in string.gmatch(args.scope, "%S+") do
table.insert(requested_scopes, scope)
end
-- 验证范围是否允许 todo
end
-- 判断用户登录检查 用户已登录,直接展示授权确认页;未登录则重定向到登录页
local user_logged_in = false
if not user_logged_in then
-- 重定向到登录页,携带当前授权请求参数(登录后跳转回来)
local login_url = "/login?redirect=" .. ngx.escape_uri(ngx_var.request_uri)
ngx.redirect(login_url)
return
end
-- 4. 处理用户授权确认(用户点击"同意"后提交 POST 请求)
if ngx_req.get_method() == "POST" then
local post_args = ngx_req.get_post_args()
if post_args.action == "allow" then
-- 5. 生成授权码(随机字符串,确保唯一性)
local function generate_code()
local str = require "resty.string"
local random = require "resty.random"
local bytes = random.bytes(16)
return str.to_hex(bytes)
end
local code = generate_code()
-- 存储授权码信息用户ID、客户端ID、scope、生成时间
local code_key = "auth_code:" .. code
local code_data = cjson.encode({
user_id = "123456",
client_id = args.client_id,
scope = args.scope or "",
created_at = ngx.time()
})
local shared_dict = ngx.shared.codeDict
shared_dict:set(code_key, code_data, 5 * 60)
-- 7. 重定向到客户端回调地址,携带授权码和原始 state防 CSRF
local redirect_url = args.redirect_uri .. "?code=" .. code .. "&state=" .. args.state
ngx.redirect(redirect_url)
return
elseif post_args.action == "deny" then
-- 用户拒绝授权,重定向到客户端并携带错误信息
local redirect_url = args.redirect_uri .. "?error=access_denied&state=" .. args.state
ngx.redirect(redirect_url)
return
end
end
end
--根据授权码获取Access-Token
function _M:token()
--读取请求体的数据
ngx.req.read_body()
----获取请求数据
--local body_data = ngx.req.get_body_data()
---- 验证数据是否符合json
--local ok = validator.validatorToken(body_data)
----验证失败则返回
--if not ok then
-- local result = resp:json(0x000001)
-- resp:send(result)
-- return
--end
-- 1. 解析请求参数(支持 form-data 和 json
local content_type = ngx.req.get_headers()["Content-Type"] or ""
local args = {}
if string.find(content_type, "application/json") then
local body = ngx.req.get_body_data()
if not body then
return ngx.exit(ngx.HTTP_BAD_REQUEST)
end
args = cjson.decode(body)
else
-- 默认解析 form-urlencoded
args = ngx.req.get_post_args()
end
-- 2. 校验必填参数
local required = {
grant_type = "refresh_token",
refresh_token = true,
client_id = true
}
if args.grant_type ~= required.grant_type then
return ngx.say(cjson.encode({
error = "unsupported_grant_type",
error_description = "grant_type must be 'refresh_token'"
}))
end
if not args.refresh_token or not args.client_id then
return ngx.say(cjson.encode({
error = "invalid_request",
error_description = "missing required parameters"
}))
end
-- 4. 校验 Refresh Token 有效性
local refresh_token = args.refresh_token
local client_id = args.client_id
-- 4.1 检查是否在黑名单(已吊销)
local is_revoked, err = red:get("refresh_blacklist:" .. refresh_token)
if is_revoked == "1" then
return ngx.say(cjson.encode({
error = "token_revoked",
error_description = "refresh_token has been revoked"
}))
end
-- 4.2 校验客户端合法性client_id 与 client_secret 匹配,仅后端客户端需要 secret
local client_secret = args.client_secret or ""
local stored_secret, err = red:get("client:" .. client_id)
if not stored_secret or stored_secret == ngx.null then
return ngx.say(cjson.encode({
error = "invalid_client",
error_description = "client_id not found"
}))
end
-- 机密客户端(如后端服务)必须验证 secret
if stored_secret ~= "public" and stored_secret ~= client_secret then
return ngx.say(cjson.encode({
error = "invalid_client",
error_description = "client_secret invalid"
}))
end
-- 4.3 验证 Refresh Token 签名(假设 Refresh Token 是 JWT 格式)
local refresh_jwt = jwt:verify(jwt_secret, refresh_token)
if not refresh_jwt.valid then
return ngx.say(cjson.encode({
error = "invalid_grant",
error_description = "refresh_token invalid: " .. (refresh_jwt.reason or "unknown")
}))
end
-- 4.4 校验 Token 绑定关系client_id 必须与 JWT 中一致)
if refresh_jwt.payload.client_id ~= client_id then
return ngx.say(cjson.encode({
error = "invalid_grant",
error_description = "refresh_token not bound to client_id"
}))
end
-- 5.1 吊销旧 Refresh Token加入黑名单设置与原有效期一致的过期时间
local ttl = refresh_jwt.payload.exp - ngx.time()
if ttl > 0 then
red:setex("refresh_blacklist:" .. refresh_token, ttl, "1")
end
local access_token_ttl = 10 * 60 --十分钟
local refresh_token_ttl = 7 * 24 * 3600 --7天
-- 5.2 生成新 Access Token
local access_payload = {
sub = refresh_jwt.payload.sub, -- 用户ID
client_id = client_id,
scope = refresh_jwt.payload.scope or "",
exp = ngx.time() + access_token_ttl,
jti = ngx.md5(ngx.time() .. math.random() .. client_id) -- 唯一标识
}
local new_access_token = jwt:sign(jwt_secret, {
header = { typ = "JWT", alg = "HS256" },
payload = access_payload
})
-- 5.3 生成新 Refresh Token滚动刷新
local refresh_payload = {
sub = refresh_jwt.payload.sub,
client_id = client_id,
scope = refresh_jwt.payload.scope or "",
exp = ngx.time() + refresh_token_ttl,
jti = ngx.md5(ngx.time() .. math.random() * 1000 .. client_id)
}
local new_refresh_token = jwt:sign(jwt_secret, {
header = { typ = "JWT", alg = "HS256" },
payload = refresh_payload
})
-- 6. 返回结果
ngx.say(cjson.encode({
access_token = new_access_token,
token_type = "Bearer",
expires_in = access_token_ttl,
refresh_token = new_refresh_token,
refresh_expires_in = refresh_token_ttl,
scope = access_payload.scope,
issued_at = ngx.time(),
jti = access_payload.jti
}))
end
--用户进行登陆然后验证返回code
function _M:login()
--获取远端客户端的IP地址
local client_ip = ngx.var.remote_addr
ngx.log(ngx.INFO, "client_ip:"..client_ip.." oauth login system")
--读取请求体的数据
ngx.req.read_body()
--获取请求数据
local body_data = ngx.req.get_body_data()
-- 验证数据是否符合json
local ok = validatorJson.validatorToken(body_data)
--验证失败则返回
--验证json数据是否正确
local ok, data = pcall(cjson.decode, body_data)
if not ok then
print("JSON解析失败:", data)
local result = resp:json(0x000001)
resp:send(result)
return
end
-- 验证数据是否符合json
local valid, errors = validator.validatorLogin(data)
--验证失败则返回
if not valid then
local result = resp:json(0x000001)
resp:send(result)
return
end
local code, ret = loginDao.login(data)
--读取数据错误
if code ~= 0 or table.getn(ret) < 0 then
local result = resp:json(0x000001)
resp:send(result)
return
end
-- 用户验证成功后返回code值:用户id当前时间和随机数进行md5后生存一个code
local user_id = ret[1].id
local username = ret[1].username
local current_time = ngx.time()
local code = ngx.md5(user_id..current_time..math.random())
-- 将code放入到共享内存中
local key = code -- 作为键值
local shared_dict = ngx.shared.codeDict
shared_dict:set(key, user_id)
-- 数据时效性先设置5分钟
shared_dict:expire(key, 5 * 60)
--发送code到前端请求
local result = resp:json(0, code)
resp:send(result)
end
--根据Access-Token获取相应用户的账户信息
@ -50,7 +292,7 @@ function _M:userinfo()
--获取请求数据
local body_data = ngx.req.get_body_data()
-- 验证数据是否符合json
local ok = validatorJson.validatorJson(body_data)
local ok = validator.validatorUserinfo(body_data)
--验证失败则返回
if not ok then
local result = resp:json(0x000001)
@ -66,13 +308,27 @@ function _M:logout()
--获取请求数据
local body_data = ngx.req.get_body_data()
-- 验证数据是否符合json
local ok = validatorJson.validatorJson(body_data)
local ok = validator.validatorLogout(body_data)
--验证失败则返回
if not ok then
local result = resp:json(0x000001)
resp:send(result)
return
end
--用户验证成功后返回code值:用户id当前时间和随机数进行md5后生存一个code
local user_id = "11"
local current_time = ngx.time()
local code = ngx.md5(user_id..current_time..math.random())
--将code放入到共享内存中
local key = user_id.."-code"
local shared_dict = ngx.shared.codeDict
shared_dict:set(key, code)
shared_dict:expire(key, 10)
--发送code到前端请求
local result = resp:json(0, code)
resp:send(result)
end
--根据Refresh-Token刷新Access-Token
@ -82,7 +338,7 @@ function _M:refresh()
--获取请求数据
local body_data = ngx.req.get_body_data()
-- 验证数据是否符合json
local ok = validatorJson.validatorJson(body_data)
local ok = validator.validatorRefresh(body_data)
--验证失败则返回
if not ok then
local result = resp:json(0x000001)
@ -98,7 +354,7 @@ function _M:checklogin()
--获取请求数据
local body_data = ngx.req.get_body_data()
-- 验证数据是否符合json
local ok = validatorJson.validatorJson(body_data)
local ok = validator.validatorLogout(body_data)
--验证失败则返回
if not ok then
local result = resp:json(0x000001)

View File

@ -20,10 +20,7 @@ function _M.getSystemDepartments()
if perm:hasPermission(role, perms) == false then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
--获取页码和请求的数据量
local pageNum = ngx.var.pagenum or 1
local pageSize = ngx.var.pagesize or 10
local code,ret = departmentDao.getSystemDepartments(pageNum, pageSize)
local code,ret = departmentDao.getSystemDepartments()
local result = resp:json(code, ret)
resp:send(result)
end

View File

@ -20,16 +20,25 @@ function _M.login()
ngx.req.read_body()
--获取请求数据
local body_data = ngx.req.get_body_data()
--验证json数据是否正确
local ok, data = pcall(cjson.decode, body_data)
if not ok then
print("JSON解析失败:", data)
local result = resp:json(0x000001)
resp:send(result)
return
end
-- 验证数据是否符合json
local retJson = validator.validatorJson(body_data)
local valid, errors = validator.validateJson(data)
--验证失败则返回
if not retJson then
if not valid then
print("验证失败: ", errors)
local result = resp:json(0x000001)
resp:send(result)
return
end
--ngx.say(body_data)
local code, ret = loginDao.login(cjson.decode(body_data))
local code, ret = loginDao.login(data)
--读取数据错误
if code ~= 0 or table.getn(ret) < 0 then
local result = resp:json(0x000001)
@ -55,8 +64,16 @@ function _M.signup()
ngx.req.read_body()
--获取请求数据
local body_data = ngx.req.get_body_data()
--验证json数据是否正确
local ok, data = pcall(cjson.decode, body_data)
if not ok then
print("JSON解析失败:", data)
local result = resp:json(0x000001)
resp:send(result)
return
end
-- 验证数据是否符合json
local retJson = validator.validatorJson(body_data)
local retJson = validator.validateJson(data)
--验证失败则返回
if not retJson then
local result = resp:json(0x000001)
@ -64,7 +81,7 @@ function _M.signup()
return
end
--ngx.say(body_data)
local code, ret = loginDao.signup(cjson.decode(body_data))
local code, ret = loginDao.signup(data)
--读取数据错误
if code ~= 0 or table.getn(ret) < 0 then
local result = resp:json(0x000001)

View File

@ -54,18 +54,16 @@ function _M.getSystemUser(m)
local role = ngx.ctx.role
--权限数据
local perms = ngx.ctx.perms
print("get getSystemUser", role, perms)
--判断当前接口用户和角色是否有权限
if perm:hasPermission(role, perms) == false then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
--获取登录的用户信息
local payload = ngx.var.uid
local metadata = m.metadata
ngx.log(ngx.INFO, "metadata value:"..metadata)
local userid = getUserId()
if userid ~= m.id then
ngx.log(ngx.WARN, "用户与使用token中的用户id不一致")
ngx.log(ngx.WARN, "用户与使用token中的用户id不一致", userid, m.id)
ngx.status = ngx.HTTP_NOT_ALLOWED
ngx.exit(ngx.HTTP_NOT_ALLOWED)
end

View File

@ -8,6 +8,7 @@ local helpers = require("share.helpers")
local jsonschema = require("jsonschema")
local cjson = require("cjson.safe")
local redis = require("share.redis")
local jwt = require("resty.jwt")
--[[
local workerId = 0 -- 假设当前机器的ID是1范围在[0, 31]之间
@ -19,6 +20,480 @@ local id = snow:generateUniqueId()-- 生成ID
--max =a and b or c--a?b:c
--local openssl = require("openssl")
--
---- 生成RSA密钥对
--local key = openssl.pkey.new {
-- algorithm = "RSA",
-- rsa = {
-- bits = 2048 -- 密钥长度
-- }
--}
--
---- 导出私钥和公钥
--local private_key_pem = key:pem() -- 获取私钥的PEM格式
--local public_key_pem = key:public_key():pem() -- 获取公钥的PEM格式
--
---- 打印密钥
--ngx.say("Private Key:"..private_key_pem)
--ngx.say("\nPublic Key:"..public_key_pem)
--
local openssl = require "resty.openssl"
local digest = require "resty.openssl.digest"
local pkey = require "resty.openssl.pkey"
local str = require "resty.string"
--获取共享字段中的键值
local key = "11-code"
local shared_dict = ngx.shared.codeDict
local codeV = shared_dict:get(key)
if codeV ~= nil then
ngx.say("code valus:".. codeV)
end
--删除共享字段中的键值
--shared_dict:delete(key)
local user_id = "11"
local client_id = "aaaasddd"
local current_time = ngx.time()
local code = ngx.md5(user_id .. client_id .. current_time .. math.random())
ngx.say("code:"..code)
ngx.say("-----")
-- 正确的schema定义
local schema = {
type = "object",
properties = {
username = { type = "string" },
password = { type = "string" },
captcha = {
type = { "string", "null" }, -- 允许string或null
minLength = 0, -- 允许空字符串
default = "" -- 默认值
},
checkKey = {
type = { "string", "null" },
minLength = 0,
default = ""
}
},
required = { "username", "password" } -- 必填字段
}
-- 原始JSON字符串
--local jsonStr = [[
--{
-- "username": "admin",
-- "password": "123456",
-- "captcha": "",
-- "checkKey": ""
--}
--]]
ngx.req.read_body()
--获取请求数据
local jsonStr = ngx.req.get_body_data()
print("read data:",jsonStr)
-- JSON解析函数
local function parse_json(json_str)
local ok, data = pcall(cjson.decode, json_str)
if not ok then
return nil, "JSON解析失败: "..data
end
return data
end
-- 验证函数
local function validateJson(data)
local validator = jsonschema.generate_validator(schema)
local valid, errors = validator(data) -- 注意返回两个值
if not valid then
return false, errors
end
return true
end
-- 完整测试流程
local testData, err = parse_json(jsonStr)
if testData then
local isValid, validationErr = validateJson(testData)
ngx.say(isValid and "验证通过" or "验证失败: "..(validationErr or "未知错误"))
else
ngx.say("验证失败: ".."未知错误")
end
do return end
-- 生成RSA密钥对
local function generate_rsa_keys(length)
local key, err = pkey.new({
type = "RSA",
bits = length or 2048
})
if not key then
return nil, nil, "生成密钥对失败: " .. (err or "未知错误")
end
-- 提取公钥PEM格式
local pub_pem, err = key:to_PEM("public")
if not pub_pem then
return nil, nil, "提取公钥失败: " .. (err or "未知错误")
end
-- 提取私钥PEM格式
local priv_pem, err = key:to_PEM("private")
if not priv_pem then
return nil, nil, "提取私钥失败: " .. (err or "未知错误")
end
return pub_pem, priv_pem, nil
end
-- 生成签名(使用私钥)
local function sign(priv_key_pem, data, algorithm)
-- 加载私钥
local priv_key, err = pkey.new(priv_key_pem)
if not priv_key then
return nil, "加载私钥失败: " .. (err or "未知错误")
end
-- 处理原始数据(字符串或文件路径)
local data_str
if type(data) == "string" then
if string.find(data, "^/") or string.find(data, "^%.%/") then
-- 从文件读取
local file, err = io.open(data, "rb")
if not file then
return nil, "读取数据文件失败: " .. (err or "未知错误")
end
data_str = file:read("*a")
file:close()
else
-- 直接使用字符串
data_str = data
end
else
return nil, "原始数据格式错误(需字符串或文件路径)"
end
-- 计算数据摘要
local md, err = digest.new(algorithm)
if not md then
return nil, "初始化摘要算法失败: " .. (err or "未知错误")
end
md:update(data_str)
-- 使用私钥对摘要签名RSA-PKCS#1填充
local signature, err = priv_key:sign(md)
if not signature then
return nil, "签名生成失败: " .. (err or "未知错误")
end
-- 签名转为Base64编码便于传输
return ngx.encode_base64(signature), nil
end
-- 验签函数(使用公钥)
local function verify(pub_key_pem, data, signature_b64, algorithm)
-- 加载公钥
local pub_key, err = pkey.new(pub_key_pem)
if not pub_key then
return false, "加载公钥失败: " .. (err or "未知错误")
end
-- 处理原始数据
local data_str
if type(data) == "string" then
if string.find(data, "^/") or string.find(data, "^%.%/") then
local file, err = io.open(data, "rb")
if not file then
return false, "读取数据文件失败: " .. (err or "未知错误")
end
data_str = file:read("*a")
file:close()
else
data_str = data
end
else
return false, "原始数据格式错误(需字符串或文件路径)"
end
-- 解码Base64签名为二进制
local signature, err = ngx.decode_base64(signature_b64)
if not signature then
return false, "签名Base64解码失败: " .. (err or "未知错误")
end
-- 计算数据摘要(与签名时一致)
local md, err = digest.new(algorithm)
if not md then
return false, "初始化摘要算法失败: " .. (err or "未知错误")
end
md:update(data_str)
-- 公钥验签
local ok, err = pub_key:verify(signature, md)
if not ok then
return false, "验签失败: " .. (err or "未知原因")
end
return true, nil
end
-- 示例:完整流程(生成密钥对 → 签名 → 验签)
local function example()
local original_data = "hello, world" -- 原始数据
local algorithm = "sha256" -- 签名算法
-- 1. 生成RSA密钥对
local pub_key, priv_key, err = generate_rsa_keys(2048)
if err then
ngx.say("密钥对生成失败: ", err)
return
end
ngx.say("公钥:\n", pub_key)
ngx.say("\n私钥:\n", priv_key)
ngx.say("\n------------------------")
-- 2. 使用私钥生成签名
local signature_b64, err = sign(priv_key, original_data, algorithm)
if err then
ngx.say("签名失败: ", err)
return
end
ngx.say("生成的签名(Base64):\n", signature_b64)
ngx.say("\n------------------------")
-- 3. 使用公钥验签
local ok, err = verify(pub_key, original_data, signature_b64, algorithm)
if ok then
ngx.say("验签成功:数据完整且签名有效")
else
ngx.say("验签失败:", err)
end
end
-- 执行示例
example()
--do
-- return
--end
-- 公钥加密(用于生成测试数据)
local function rsa_encrypt(pub_key, plaintext)
--
local pkey, err = pkey.new(pub_key)
if not pkey or not plaintext then
return nil, "参数错误"
end
local oaep_params = {
oaep_md = "sha256", -- 对应pkey.lua中的opts.oaep_md
mgf1_md = "sha256", -- 对应pkey.lua中的opts.mgf1_md
label = nil
}
local RSA_PKCS1_OAEP_PADDING = "4"
local ciphertext, err = pkey:encrypt(plaintext, RSA_PKCS1_OAEP_PADDING, oaep_params)
if not ciphertext then
return nil, "加密失败: " .. (err or "未知错误")
end
-- 返回Base64编码的密文便于传输存储
return ngx.encode_base64(ciphertext), nil
end
-- 私钥解密(核心实现)
local function rsa_decrypt(priv_key, encrypted_data)
local pkey, err = pkey.new(priv_key)
if not pkey or not encrypted_data then
return nil, "参数错误(私钥或密文为空)"
end
-- 1. 先解码Base64密文
local ciphertext, err = ngx.decode_base64(encrypted_data)
if not ciphertext then
return nil, "Base64解码失败: " .. (err or "无效密文")
end
-- 2. 设置解密填充方式(必须与加密时一致)
local oaep_params = {
oaep_md = "sha256", -- 对应pkey.lua中的opts.oaep_md
mgf1_md = "sha256", -- 对应pkey.lua中的opts.mgf1_md
label = nil
}
local RSA_PKCS1_OAEP_PADDING = "4"
-- 3. 执行解密
local result, err = pkey:decrypt(ciphertext, RSA_PKCS1_OAEP_PADDING, oaep_params)
if not result then
return nil, "解密返回空结果"
end
return result, nil -- 返回解密后的原始数据
end
-- 完整测试流程
local function test_rsa_crypto()
-- 1. 生成密钥对
local pub_key, priv_key, err = generate_rsa_keys(2048)
if err then
return nil, "密钥生成失败: " .. err
end
ngx.say(pub_key)
ngx.say("-----")
ngx.say(priv_key)
ngx.say("-----")
-- 2. 原始数据
local original_text = "这是一段需要加密的敏感数据123456"
ngx.say("原始数据: ", original_text)
-- 3. 公钥加密
local encrypted_data, err = rsa_encrypt(pub_key, original_text)
if err then
return nil, "加密失败: " .. err
end
ngx.say("公钥加密后(Base64): ", encrypted_data)
-- 4. 私钥解密
local decrypted_text, err = rsa_decrypt(priv_key, encrypted_data)
if err then
return nil, "私钥解密失败: " .. err
end
ngx.say("私钥解密后: ", decrypted_text)
ngx.say("私钥解密后hex: ", str.to_hex(decrypted_text))
-- 5. 验证结果
if decrypted_text ~= original_text then
return nil, "解密结果不匹配原始数据"
end
-------------------------------
-- 要签名的数据
local md5val = original_text --ngx.md5(original_text) -- 使用MD5作为摘要算法你也可以使用其他如sha256等
---- 生成签名------------------
-- 使用SHA256算法
local md = digest.new("sha256")
-- 更新签名上下文,提供数据以供签名
md:update(md5val)
-- 完成签名
local privK, err = pkey.new(priv_key)
if not privK then
return nil, "参数错误(私钥或密文为空)"
end
local signature, err = privK:sign(md)
if not signature then
ngx.log(ngx.ERR, "Failed to generate signature: ", err)
return
end
ngx.say("签名数据1: ", signature)
local encode_date = ngx.encode_base64(signature)
ngx.say("签名数据加密后(Base64)", encode_date)
---- 验证签名------------------
local pubK, err = pkey.new(pub_key)
if not pubK then
return nil, "参数错误(私钥或密文为空)"
end
local digestP = digest.new("sha256")
-- 更新签名上下文,提供数据以供签名
digestP:update(md5val)
local signature1 = ngx.decode_base64(encode_date)
ngx.say("签名数据2: ", signature1)
local is_valid = pubK:verify(signature1, digestP) -- 使用与签名相同的摘要算法进行验证
if is_valid then
ngx.say("Signature is valid.")
else
ngx.say("Signature is invalid.")
end
-----------------------------------
return true, "加密解密验证成功"
end
-- 1. 生成密钥对
local pub_key, priv_key, err = generate_rsa_keys(2048)
if err then
return nil, "密钥生成失败: " .. err
end
-- 私钥和公钥
local private_key = priv_key
local public_key = pub_key
-- 创建JWT的payload
local payload = {
iss = "https://example.com",
sub = "1234567890",
name = "John Doe",
iat = os.time(),
exp = os.time() + 3600
}
-- 使用私钥生成JWT
local jwt_obj = jwt:sign(private_key, {
header = {
type = "JWT",
alg = "RS256"
},
payload = payload
})
if not jwt_obj then
ngx.say("Failed to generate JWT")
return
end
ngx.say("Generated JWT: ", jwt_obj)
-- 使用公钥校验JWT
local decoded, res = jwt:verify(public_key, jwt_obj)
if not decoded then
ngx.say("Failed to verify JWT: ", cjson.encode(res))
return
end
ngx.say("JWT is valid: ", cjson.encode(decoded))
--local original_text = "这是一段需要加密的敏感数据123456"
--local key = x509.PKey()
--key:generate_key("rsa", 2048) -- 生成 RSA 密钥2048 位长度
--
--local cert = x509.X509()
--cert:set_version(2) -- 设置证书版本为 2 (RFC 5280)
--cert:set_serial_number({0x01, 0x02, 0x03}) -- 设置序列号
--cert:set_issuer_name([[
-- C=US, ST=Texas, L=Houston, O=Example Inc, OU=IT, CN=example.com
-- ]]) -- 设置颁发者名称
--cert:set_subject_name([[
-- C=US PARTICULARITY, ST=Texas, L=Houston, O=Example Inc, OU=IT, CN=example.com
-- ]]) -- 设置主题名称(与颁发者相同或不同)
--cert:set_pubkey(key) -- 设置公钥
--
--cert:set_not_before(os.time()) -- 设置生效时间(当前时间)
--cert:set_not_after(os.time() + 60*60*24*365) -- 设置过期时间(一年后)
--
--cert:sign(key, "sha256") -- 使用私钥和 SHA256 签名证书
--
--local key_pem = pem.to_pem(key) -- 将密钥转换为 PEM 格式
--local cert_pem = pem.to_pem(cert) -- 将证书转换为 PEM 格式
-- 输出或保存到文件
--ngx.say(key_pem)
--ngx.say(cert_pem)
-- 执行测试
local success, msg = test_rsa_crypto()
if success then
ngx.say("测试成功: \n", msg)
else
ngx.status = 500
ngx.say("测试失败: \n", msg)
end
ngx.say("-----")
--[[
local radix = require("resty.radixtree")
@ -138,7 +613,7 @@ for i = 1, #uid do
table.insert(result, string.sub(charset, rand, rand))
end
print(generate_12char_uuid()) -- 示例输出aB3eF7hJ9kL2
--print(generate_12char_uuid()) -- 示例输出aB3eF7hJ9kL2
--[[
local args = ngx.req.get_uri_args()

View File

@ -4,7 +4,7 @@
--- DateTime: 2025/11/3 11:38
---
local rbac = require("util.rbac")
local rbac = require("util.rsa")
-- 创建RBAC实例
local permission_system = rbac.new()

View File

@ -18,12 +18,14 @@ end
-- 检查角色是否拥有指定权限
function _M:hasPermission(role_name, permission)
do return true end
if role_name == nil or permission == nil then
return false
end
-- 检查直接权限
local key = role_name.."-"..permission
print("get permission key:", key)
local res, err = red:get(key)
if res ~= nil then
return true

View File

@ -1,93 +0,0 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by admin.
--- DateTime: 2025/11/3 11:31
---
local RBAC = {}
RBAC.__index = RBAC
-- RBAC模型初始化
function RBAC.new()
local self = setmetatable({}, RBAC)
self.users = {} -- 用户表: {user_id = {roles = {role1, role2}}}
self.roles = {} -- 角色表: {role_name = {permissions = {perm1, perm2}}}
self.permissions = {} -- 权限表: {perm_name = {resource = "", action = ""}}
return self
end
-- 添加权限
function RBAC:add_permission(perm_name, resource, action)
self.permissions[perm_name] = {
resource = resource,
action = action
}
end
-- 添加角色并分配权限
function RBAC:add_role(role_name, permissions)
self.roles[role_name] = {
permissions = permissions or {}
}
end
-- 分配角色给用户
function RBAC:assign_role(user_id, role_name)
if not self.users[user_id] then
self.users[user_id] = {roles = {}}
end
table.insert(self.users[user_id].roles, role_name)
end
-- 检查用户权限
function RBAC:check_permission(user_id, resource, action)
local user = self.users[user_id]
if not user then return false end
for _, role_name in ipairs(user.roles) do
local role = self.roles[role_name]
if role then
for _, perm_name in ipairs(role.permissions) do
local permission = self.permissions[perm_name]
if permission and permission.resource == resource and permission.action == action then
return true
end
end
end
end
return false
end
-- 获取用户所有权限
function RBAC:get_user_permissions(user_id)
local user_permissions = {}
local user = self.users[user_id]
if not user then return user_permissions end
for _, role_name in ipairs(user.roles) do
local role = self.roles[role_name]
if role then
for _, perm_name in ipairs(role.permissions) do
table.insert(user_permissions, self.permissions[perm_name])
end
end
end
return user_permissions
end
-- 添加角色
--_, err = permit.AddPolicy(roleName, roleId, action)
-- 赋予用户角色
--_, err = permit.AddRoleForUser(user, roleName)
-- 查看具有某角色的所有用户
--res, err = permit.GetUsersForRole(roleName)
-- 移除用户具有的角色
--_, err = permit.DeleteRoleForUser(user, roleName)
-- 移除角色,跟角色相关联的用户都被移除
--_, err = permit.DeleteRole(roleName)
return RBAC

View File

@ -1,14 +1,14 @@
local cjson = require('cjson')
local conf = require('config')
local error_code = require('util.status')
local ngx = ngx
local _M = {}
function _M:json(status, message, data, http_status)
-- you can modify this response struct as you favor
if status == 0 then status = ngx.HTTP_OK end
local msg = message
local response_status = http_status or ngx.OK
local response_status = http_status or ngx.HTTP_OK
if msg == nil or msg == '' then
--local locale = ngx.ctx.locale or conf.locale
--if error_code[locale] ~= nil then
@ -16,7 +16,7 @@ function _M:json(status, message, data, http_status)
--end
msg = error_code[status]
end
local response = {code=status, msg=msg, result=data,timestamp=ngx.time()}
local response = {code = status, msg = msg, result = data,timestamp = ngx.time()}
if not response.code then
response.code = -1
response.message = 'not find status code'
@ -30,11 +30,12 @@ end
function _M:json(status, data, http_status)
-- you can modify this response struct as you favor
if status == 0 then status = ngx.HTTP_OK end
local msg = ''
local response_status = http_status or ngx.OK
local response_status = http_status or ngx.HTTP_OK
msg = error_code[status]
local response = {code=status, msg=msg, result=data,timestamp=ngx.time()}
local response = {code = status, msg = msg, result = data,timestamp = ngx.time()}
if not response.code then
response.code = -1
response.message = 'not find status code'

80
src/util/rsa.lua Normal file
View File

@ -0,0 +1,80 @@
local pkey = require "resty.openssl.pkey"
local str = require "resty.string"
local _M = {}
-- 生成密钥对
function _M:generate_rsa_keys(length)
-- 生成2048位RSA密钥对
local key, err = pkey.new({
type = "RSA",
bits = length or 2048
})
-- 提取公钥
local pub_pem = key:to_PEM("public")
-- 提取私钥
local priv_pem = key:to_PEM("private")
if not priv_pem or not pub_pem then
return nil, nil, "转换 PEM 格式失败: " .. (err or "未知错误")
end
return pub_pem, priv_pem, nil
end
-- 公钥加密(用于生成测试数据)
function _M:rsa_encrypt(pub_key, plaintext)
--
local pkey, err = pkey.new(pub_key)
if not pkey or not plaintext then
return nil, "参数错误"
end
local oaep_params = {
oaep_md = "sha256", -- 对应pkey.lua中的opts.oaep_md
mgf1_md = "sha256", -- 对应pkey.lua中的opts.mgf1_md
label = nil
}
local RSA_PKCS1_OAEP_PADDING = "4"
local ciphertext, err = pkey:encrypt(plaintext, RSA_PKCS1_OAEP_PADDING ,oaep_params)
if not ciphertext then
return nil, "加密失败: " .. (err or "未知错误")
end
-- 返回Base64编码的密文便于传输存储
return ngx.encode_base64(ciphertext), nil
end
-- 私钥解密(核心实现)
function _M:rsa_decrypt(private_key, encrypted_data)
local pkey, err = pkey.new(private_key)
if not pkey or not encrypted_data then
return nil, "参数错误(公钥或密文为空)"
end
-- 1. 先解码Base64密文
local ciphertext, err = ngx.decode_base64(encrypted_data)
if not ciphertext then
return nil, "Base64解码失败: " .. (err or "无效密文")
end
-- 2. 设置解密填充方式(必须与加密时一致)
local oaep_params = {
oaep_md = "sha256", -- 对应pkey.lua中的opts.oaep_md
mgf1_md = "sha256", -- 对应pkey.lua中的opts.mgf1_md
label = nil
}
local RSA_PKCS1_OAEP_PADDING = "4"
-- 3. 执行解密
local result, err = pkey:decrypt(ciphertext, RSA_PKCS1_OAEP_PADDING, oaep_params)
if not result then
return nil, "解密返回空结果"
end
return result, nil -- 返回解密后的原始数据
end
return _M

View File

@ -18,7 +18,7 @@
--ngx.HTTP_GATEWAY_TIMEOUT (504)
return {
-- 系统状态码
[0x000000] = 'ok',
[0x0000C8] = 'ok',
[0x000001] = '验证错误',
[0x000002] = '系统错误',
[0x000003] = '系统异常',

View File

@ -9,12 +9,15 @@ local _M = {}
-- 定义一个JSON Schema
local schemaAuth = {
{type = "object", properties = {
{name = "username", type = "string"},
{name = "password", type = "string"},
{name = "captcha", type = "string"},
{name = "checkKey", type = "string"},
}, required = {"username", "password"}}
type = "object",
properties = {
response_type = { type = "string" },
client_id = { type = "string" },
redirect_uri = { type = "string" },
scope = { type = "string" },
state = { type = "string" },
},
required = { "response_type", "client_id", "redirect_uri" }
}
--获取授权码
@ -26,12 +29,13 @@ function _M:validatorAuthorize(jsonData)
end
local schemaToken = {
{type = "object", properties = {
{name = "username", type = "string"},
{name = "password", type = "string"},
{name = "captcha", type = "string"},
{name = "checkKey", type = "string"},
}, required = {"username", "password"}}
type = "object",
properties = {
grant_type = { type = "string" },
code = { type = "string" },
redirect_uri = { type = "string" },
},
required = { "grant_type", "code", "redirect_uri" }
}
--根据授权码获取Access-Token
@ -42,13 +46,31 @@ function _M:validatorToken(jsonData)
return result
end
local schemaLogin = {
type = "object",
properties = {
username = { type = "string" },
password = { type = "string" },
captcha = { type = "string" },
checkKey = { type = "string" },
},
required = { "username", "password" }
}
--回收Access-Token
function _M:validatorLogin(jsonData)
-- 验证数据是否符合schema
local validator = jsonschema.generate_validator(schemaLogin)
local result = validator(jsonData)
return result
end
local schemaUserInfo = {
{type = "object", properties = {
{name = "username", type = "string"},
{name = "password", type = "string"},
{name = "captcha", type = "string"},
{name = "checkKey", type = "string"},
}, required = {"username", "password"}}
type = "object",
properties = {
Authorization = { type = "string" },
},
required = { "Authorization" }
}
--根据Access-Token获取相应用户的账户信息
@ -60,12 +82,11 @@ function _M:validatorUserinfo(jsonData)
end
local schemaLogout = {
{type = "object", properties = {
{name = "username", type = "string"},
{name = "password", type = "string"},
{name = "captcha", type = "string"},
{name = "checkKey", type = "string"},
}, required = {"username", "password"}}
type = "object",
properties = {
Authorization = { type = "string" },
},
required = { "Authorization" }
}
--回收Access-Token
@ -77,12 +98,11 @@ function _M:validatorLogout(jsonData)
end
local schemaRefresh = {
{type = "object", properties = {
{name = "username", type = "string"},
{name = "password", type = "string"},
{name = "captcha", type = "string"},
{name = "checkKey", type = "string"},
}, required = {"username", "password"}}
type = "object",
properties = {
Authorization = { type = "string" },
},
required = { "Authorization" }
}
--根据Refresh-Token刷新Access-Token
@ -94,12 +114,11 @@ function _M:validatorRefresh(jsonData)
end
local schemaChecklogin = {
{type = "object", properties = {
{name = "username", type = "string"},
{name = "password", type = "string"},
{name = "captcha", type = "string"},
{name = "checkKey", type = "string"},
}, required = {"username", "password"}}
type = "object",
properties = {
Authorization = { type = "string" },
},
required = { "Authorization" }
}
--验证token是否有效

View File

@ -9,15 +9,17 @@ local _M = {}
-- 定义一个JSON Schema
local schema = {
{type = "object", properties = {
{name = "name", type = "string"},
{name = "password", type = "string"},
{name = "real_name", type = "string"},
{name = "department", type = "string"},
{name = "office_phone", type = "string"},
{name = "telephone", type = "string"},
{name = "display_name", type = "string"},
}, required = {"name"}}
type = "object",
properties = {
name = { type = "string" },
password = { type = "string" },
real_name = { type = "string" },
department = { type = "string" },
office_phone = { type = "string" },
create_by = { type = "string" },
update_by = { type = "string" },
},
required = { "name", "redirect_uris" }
}
function _M.validatorJson(jsonData)

View File

@ -9,17 +9,18 @@ local _M = {}
-- 定义一个JSON Schema
local schema = {
{type = "object", properties = {
{name = "name", type = "string"},
{name = "display_name", type = "string"},
{name = "logo", type = "string"},
{name = "title", type = "string"},
{name = "name", type = "string"},
{name = "favicon", type = "string"},
{name = "description", type = "string"},
{name = "homepage_url", type = "string"},
{name = "redirect_uris", type = "string"},
}, required = {"name", "redirect_uris"}}
type = "object",
properties = {
name = { type = "string" },
display_name = { type = "string" },
logo = { type = "string" },
title = { type = "string" },
favicon = { type = "string" },
description = { type = "string" },
homepage_url = { type = "string" },
redirect_uris = { type = "string" },
},
required = { "name", "redirect_uris" }
}
function _M.validatorJson(jsonData)

View File

@ -9,16 +9,18 @@ local _M = {}
-- 定义一个JSON Schema
local schema = {
{type = "object", properties = {
{name = "name", type = "string"},
{name = "seq", type = "string"},
{name = "description", type = "string"},
{name = "create_by", type = "string"},
{name = "update_by", type = "string"},
{name = "parent_id", type = "string"},
{name = "leader", type = "string"},
{name = "status", type = "string"},
}, required = {"name"}}
type = "object",
properties = {
name = { type = "string" },
seq = { type = "string" },
description = { type = "string" },
create_by = { type = "string" },
update_by = { type = "string" },
parent_id = { type = "string" },
leader = { type = "string" },
status = { type = "string" },
},
required = { "name" }
}
function _M.validatorJson(jsonData)

View File

@ -9,19 +9,33 @@ local _M = {}
-- 定义一个JSON Schema
local schema = {
{type = "object", properties = {
{name = "username", type = "string"},
{name = "password", type = "string"},
{name = "captcha", type = "string"},
{name = "checkKey", type = "string"},
}, required = {"username", "password"}}
type = "object",
properties = {
username = { type = "string" },
password = { type = "string" },
captcha = {
type = { "string", "null" }, -- 允许string或null
minLength = 0, -- 允许空字符串
default = "" -- 默认值
},
checkKey = {
type = { "string", "null" },
minLength = 0,
default = ""
}
},
required = { "username", "password" } -- 必填字段
}
function _M.validatorJson(jsonData)
-- 验证数据是否符合schema
-- 验证函数
function _M.validateJson(data)
local validator = jsonschema.generate_validator(schema)
local result = validator(jsonData)
return result
local valid, errors = validator(data) -- 注意返回两个值
if not valid then
return false, errors
end
return true
end
return _M

View File

@ -9,16 +9,15 @@ local _M = {}
-- 定义一个JSON Schema
local schema = {
{type = "object", properties = {
{name = "username", type = "string"},
{name = "phone", type = "string"},
{name = "email", type = "string"},
{name = "idcard", type = "string"},
{name = "name", type = "string"},
{name = "office_phone", type = "string"},
{name = "telephone", type = "string"},
{name = "display_name", type = "string"},
}, required = {"username", "phone", "email", "idcard"}}
type = "object",
properties = {
permission_name = { type = "string" },
permission_code = { type = "string" },
permission_desc = { type = "string" },
create_by = { type = "string" },
update_by = { type = "string" },
},
required = { "permission_name", "permission_code" }
}
function _M.validatorJson(jsonData)

View File

@ -9,15 +9,17 @@ local _M = {}
-- 定义一个JSON Schema
local schema = {
{type = "object", properties = {
{name = "post_id", type = "string"},
{name = "post_code", type = "string"},
{name = "post_name", type = "string"},
{name = "post_sort", type = "number"},
{name = "status", type = "string"},
{name = "create_by", type = "string"},
{name = "update_by", type = "string"},
}, required = {"post_id"}}
type = "object",
properties = {
post_id = { type = "string" },
post_code = { type = "string" },
post_name = { type = "string" },
post_sort = { type = "number" },
status = { type = "string" },
create_by = { type = "string" },
update_by = { type = "string" },
},
required = { "post_id" }
}
function _M.validatorJson(jsonData)

View File

@ -9,12 +9,14 @@ local _M = {}
-- 定义一个JSON Schema
local schema = {
{type = "object", properties = {
{name = "role_name", type = "string"},
{name = "description", type = "string"},
{name = "create_by", type = "string"},
{name = "update_by", type = "string"},
}, required = {"role_name"}}
type = "object",
properties = {
role_name = { type = "string" },
description = { type = "string" },
create_by = { type = "string" },
update_by = { type = "string" },
},
required = { "role_name" }
}
function _M.validatorJson(jsonData)

View File

@ -9,16 +9,17 @@ local _M = {}
-- 定义一个JSON Schema
local schema = {
{type = "object", properties = {
{name = "username", type = "string", minLength = 8, maxLength = 20},
{name = "phone", type = "string",minLength = 11},
{name = "email", type = "string"},
{name = "idcard", type = "string"},
{name = "name", type = "string"},
{name = "office_phone", type = "string"},
{name = "telephone", type = "string",minLength = 11},
{name = "display_name", type = "string"},
}, required = {"username", "phone", "email", "idcard"}}
type = "object",
properties = {
username = { type = "string" },
phone = { type = "string" },
email = { type = "string" },
idcard = { type = "string" },
office_phone = { type = "string" },
telephone = { type = "string" },
display_name = { type = "string" },
},
required = { "username", "phone", "email", "idcard" }
}
function _M.validatorJson(jsonData)