Compare commits
4 Commits
64b4e82145
...
42b62500e4
| Author | SHA1 | Date | |
|---|---|---|---|
| 42b62500e4 | |||
|
|
1cf799c51b | ||
| b0967b428c | |||
|
|
eb4228a200 |
|
|
@ -1,12 +1,14 @@
|
||||||
local jwt = require "resty.jwt"
|
local jwt = require "resty.jwt"
|
||||||
local validators = require "resty.jwt-validators"
|
local cjson = require("cjson.safe")
|
||||||
local conf = require("config")
|
local conf = require("config")
|
||||||
|
local jsonschema = require("jsonschema")
|
||||||
|
|
||||||
-- 定义一个JSON Schema
|
-- 定义一个JSON Schema
|
||||||
local schema = {
|
local schema = {
|
||||||
{type = "object", properties = {
|
type = 'object',
|
||||||
{name = "username", type = "string", minLength = 8, maxLength = 20},
|
properties = {
|
||||||
}, required = {"username", "phone", "email", "idcard"}}
|
Authorization = {type = 'string', minLength = 8, pattern = 'Bearer\\s+(.+)$'},
|
||||||
|
}, required = {"Authorization"}
|
||||||
}
|
}
|
||||||
|
|
||||||
--获取用户认证数据信息
|
--获取用户认证数据信息
|
||||||
|
|
@ -19,17 +21,20 @@ if auth_header == nil or auth_header == "" then
|
||||||
ngx.exit(ngx.HTTP_UNAUTHORIZED)
|
ngx.exit(ngx.HTTP_UNAUTHORIZED)
|
||||||
end
|
end
|
||||||
|
|
||||||
--查找令牌中的Bearer前缀字符,并进行截取 todo 使用jsonscheme进行匹配
|
--查找令牌中的Bearer前缀字符
|
||||||
local _, _, token = string.find(auth_header, "Bearer%s+(.+)")
|
local validator = jsonschema.generate_validator(schema)
|
||||||
--如果没有Bearer,则表示令牌格式不正确
|
local data = {}
|
||||||
if token == nil then
|
data.Authorization = auth_header
|
||||||
|
local ok = validator(data)
|
||||||
|
if not ok then
|
||||||
ngx.log(ngx.WARN, "令牌格式不正确")
|
ngx.log(ngx.WARN, "令牌格式不正确")
|
||||||
ngx.status = ngx.HTTP_UNAUTHORIZED
|
ngx.status = ngx.HTTP_UNAUTHORIZED
|
||||||
ngx.exit(ngx.HTTP_UNAUTHORIZED)
|
ngx.exit(ngx.HTTP_UNAUTHORIZED)
|
||||||
end
|
end
|
||||||
|
--获取token的数据值
|
||||||
|
local token = string.sub(auth_header,8)
|
||||||
--校验令牌
|
--校验令牌
|
||||||
local jwt_obj = jwt:verify(conf.secret_key, auth_header)
|
local jwt_obj = jwt:verify(conf.secret_key, token)
|
||||||
--如果校验结果中的verified==false,则表示令牌无效
|
--如果校验结果中的verified==false,则表示令牌无效
|
||||||
if jwt_obj.verified == false then
|
if jwt_obj.verified == false then
|
||||||
ngx.log(ngx.WARN, "Invalid token: ".. jwt_obj.reason)
|
ngx.log(ngx.WARN, "Invalid token: ".. jwt_obj.reason)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
---
|
---
|
||||||
--local snowflake = require("util.snowflake")
|
--local snowflake = require("util.snowflake")
|
||||||
local helpers = require("share.helpers")
|
local helpers = require("share.helpers")
|
||||||
|
local jsonschema = require("jsonschema")
|
||||||
|
local cjson = require("cjson.safe")
|
||||||
--
|
--
|
||||||
--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]之间
|
||||||
|
|
@ -14,7 +16,6 @@ local helpers = require("share.helpers")
|
||||||
|
|
||||||
--max =a and b or c--a?b:c
|
--max =a and b or c--a?b:c
|
||||||
|
|
||||||
local cjson = require("cjson.safe")
|
|
||||||
--[[
|
--[[
|
||||||
local uuid = require("resty.jit-uuid")
|
local uuid = require("resty.jit-uuid")
|
||||||
uuid.seed()
|
uuid.seed()
|
||||||
|
|
@ -32,16 +33,34 @@ local pageSize = args["pagesize"] or 10
|
||||||
ngx.say("pageNum:", pageNum, " pageSize:", pageSize)
|
ngx.say("pageNum:", pageNum, " pageSize:", pageSize)
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
|
local schema = {
|
||||||
|
type = 'object',
|
||||||
|
properties = {
|
||||||
|
Authorization = {type = 'string', minLength = 10, pattern = 'Bearer\\s+(.+)$'},
|
||||||
|
}, required = {"Authorization"}
|
||||||
|
}
|
||||||
|
|
||||||
local cjson = require "cjson"
|
--获取用户认证数据信息
|
||||||
--local sampleJson = [[{"age":"23","testArray":{"array":[8,9,11,14,25]},"Himi":"himigame.com"}]]
|
local data = {}
|
||||||
local sampleJson = [[{"raw_header":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9","signature":"zkKAmXifqWDrMaLpXe8hrA1JpDRbdlgwS-yxNnQUOBw","raw_payload":"eyJpYXQiOjE3NjE4OTIwNDMsImV4cCI6MTc2MTg5NTY0MywidXNlcmlkIjoiYWRtaW4iLCJyb2xlIjoiIn0","valid":true,"verified":true,"reason":"everything is awesome~ :p","header":{"alg":"HS256","typ":"JWT"},"payload":{"iat":1761892043,"userid":"admin","exp":1761895643,"role":""}}]]
|
local auth_header = ngx.var.http_Authorization
|
||||||
--解析json字符串
|
data.Authorization = auth_header
|
||||||
local data = cjson.decode(sampleJson);
|
local validator = jsonschema.generate_validator(schema)
|
||||||
--打印json字符串中的age字段
|
local result = validator(data)
|
||||||
ngx.say(data["raw_header"]);
|
if not result then
|
||||||
--打印数组中的第一个值(lua默认是从0开始计数)
|
ngx.log(ngx.WARN, "令牌格式不正确")
|
||||||
ngx.say(data["payload"]["userid"]);
|
ngx.status = ngx.HTTP_UNAUTHORIZED
|
||||||
|
ngx.exit(ngx.HTTP_UNAUTHORIZED)
|
||||||
|
end
|
||||||
|
local token = string.sub(auth_header,8)
|
||||||
|
ngx.say(token)
|
||||||
|
|
||||||
|
--local sampleJson = [[{"raw_header":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9","signature":"zkKAmXifqWDrMaLpXe8hrA1JpDRbdlgwS-yxNnQUOBw","raw_payload":"eyJpYXQiOjE3NjE4OTIwNDMsImV4cCI6MTc2MTg5NTY0MywidXNlcmlkIjoiYWRtaW4iLCJyb2xlIjoiIn0","valid":true,"verified":true,"reason":"everything is awesome~ :p","header":{"alg":"HS256","typ":"JWT"},"payload":{"iat":1761892043,"userid":"admin","exp":1761895643,"role":""}}]]
|
||||||
|
----解析json字符串
|
||||||
|
--local data = cjson.decode(sampleJson);
|
||||||
|
----打印json字符串中的age字段
|
||||||
|
--ngx.say(data["raw_header"]);
|
||||||
|
----打印数组中的第一个值(lua默认是从0开始计数)
|
||||||
|
--ngx.say(data["payload"]["userid"]);
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
local jwttoken = require("util.token")
|
local jwttoken = require("util.token")
|
||||||
|
|
@ -92,6 +111,7 @@ else
|
||||||
end
|
end
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
|
--[[
|
||||||
--用于接收前端数据的对象
|
--用于接收前端数据的对象
|
||||||
local args=nil
|
local args=nil
|
||||||
--获取前端的请求方式 并获取传递的参数
|
--获取前端的请求方式 并获取传递的参数
|
||||||
|
|
@ -112,6 +132,7 @@ end
|
||||||
local name =
|
local name =
|
||||||
--响应前端
|
--响应前端
|
||||||
ngx.say("linux hello:"..name)
|
ngx.say("linux hello:"..name)
|
||||||
|
--]]
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
|
||||||
62
src/test/testRBAC.lua
Normal file
62
src/test/testRBAC.lua
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
---
|
||||||
|
--- Generated by EmmyLua(https://github.com/EmmyLua)
|
||||||
|
--- Created by admin.
|
||||||
|
--- DateTime: 2025/11/3 11:38
|
||||||
|
---
|
||||||
|
|
||||||
|
local rbac = require("util.rbac")
|
||||||
|
|
||||||
|
-- 创建RBAC实例
|
||||||
|
local permission_system = rbac.new()
|
||||||
|
|
||||||
|
-- 定义权限
|
||||||
|
permission_system:add_permission("read_users", "/users", "GET")
|
||||||
|
permission_system:add_permission("create_users", "/users", "POST")
|
||||||
|
permission_system:add_permission("delete_users", "/users", "DELETE")
|
||||||
|
permission_system:add_permission("admin_panel", "/admin", "GET")
|
||||||
|
|
||||||
|
-- 定义角色
|
||||||
|
permission_system:add_role("guest", {"read_users"})
|
||||||
|
permission_system:add_role("user_manager", {"read_users", "create_users"})
|
||||||
|
permission_system:add_role("super_admin", {"read_users", "create_users", "delete_users", "admin_panel"})
|
||||||
|
|
||||||
|
-- 分配角色给用户
|
||||||
|
permission_system:assign_role("user001", "guest")
|
||||||
|
permission_system:assign_role("user002", "user_manager")
|
||||||
|
permission_system:assign_role("admin001", "super_admin")
|
||||||
|
|
||||||
|
-- 测试权限验证
|
||||||
|
print("=== RBAC权限验证测试 ===")
|
||||||
|
|
||||||
|
-- 测试用户001(guest角色)
|
||||||
|
local test_cases = {
|
||||||
|
{user_id = "user001", resource = "/users", action = "GET", expected = true},
|
||||||
|
{user_id = "user001", resource = "/users", action = "POST", expected = false},
|
||||||
|
{user_id = "user001", resource = "/admin", action = "GET", expected = false},
|
||||||
|
|
||||||
|
{user_id = "user002", resource = "/users", action = "GET", expected = true},
|
||||||
|
{user_id = "user002", resource = "/users", action = "POST", expected = true},
|
||||||
|
{user_id = "user002", resource = "/admin", action = "GET", expected = false},
|
||||||
|
|
||||||
|
{user_id = "admin001", resource = "/users", action = "GET", expected = true},
|
||||||
|
{user_id = "admin001", resource = "/users", action = "DELETE", expected = true},
|
||||||
|
{user_id = "admin001", resource = "/admin", action = "GET", expected = true}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test in ipairs(test_cases) do
|
||||||
|
local result = permission_system:check_permission(test.user_id, test.resource, test.action)
|
||||||
|
local status = result == test.expected and "✓ 通过" or "✗ 失败"
|
||||||
|
print(string.format("%s 用户:%s 资源:%s 方法:%s 结果:%s",
|
||||||
|
status, test.user_id, test.resource, test.action, tostring(result)))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 显示用户权限列表
|
||||||
|
print("\n=== 用户权限列表 ===")
|
||||||
|
local users = {"user001", "user002", "admin001"}
|
||||||
|
for _, user_id in ipairs(users) do
|
||||||
|
local permissions = permission_system:get_user_permissions(user_id)
|
||||||
|
print(string.format("用户 %s 的权限:", user_id))
|
||||||
|
for _, perm in ipairs(permissions) do
|
||||||
|
print(string.format(" - %s %s", perm.action, perm.resource))
|
||||||
|
end
|
||||||
|
end
|
||||||
78
src/util/rbac.lua
Normal file
78
src/util/rbac.lua
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
---
|
||||||
|
--- 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
|
||||||
|
|
||||||
|
return RBAC
|
||||||
|
|
@ -6,9 +6,17 @@
|
||||||
|
|
||||||
local jwt = require("resty.jwt")
|
local jwt = require("resty.jwt")
|
||||||
local conf = require("config")
|
local conf = require("config")
|
||||||
|
local jsonschema = require("jsonschema")
|
||||||
|
|
||||||
local _M = {}
|
local _M = {}
|
||||||
|
|
||||||
|
local schema = {
|
||||||
|
type = 'object',
|
||||||
|
properties = {
|
||||||
|
Authorization = {type = 'string', minLength = 10, pattern = 'Bearer\\s+(.+)$'},
|
||||||
|
}, required = {"Authorization"}
|
||||||
|
}
|
||||||
|
|
||||||
--设置JWT的有效载荷
|
--设置JWT的有效载荷
|
||||||
local obj = {
|
local obj = {
|
||||||
header = {typ="JWT", alg="HS256"},
|
header = {typ="JWT", alg="HS256"},
|
||||||
|
|
@ -46,17 +54,21 @@ function _M.authorizationToken(auth_header)
|
||||||
return response
|
return response
|
||||||
end
|
end
|
||||||
|
|
||||||
--查找令牌中的Bearer前缀字符,并进行截取
|
local validator = jsonschema.generate_validator(schema)
|
||||||
local _, _, token = string.find(auth_header, "Bearer%s+(.+)")
|
local data = {}
|
||||||
|
data.Authorization = auth_header
|
||||||
|
local ok = validator(data)
|
||||||
--如果没有Bearer,则表示令牌无效
|
--如果没有Bearer,则表示令牌无效
|
||||||
if token == nil then
|
if not ok then
|
||||||
response["code"] = 401
|
response["code"] = 401
|
||||||
response["message"] = "令牌格式不正确"
|
response["message"] = "令牌格式不正确"
|
||||||
return response
|
return response
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--查找令牌中的Bearer前缀字符,并进行截取
|
||||||
|
local token = string.sub(auth_header,8)
|
||||||
--校验令牌
|
--校验令牌
|
||||||
local jwt_obj = jwt:verify(conf.secret_key, auth_header)
|
local jwt_obj = jwt:verify(conf.secret_key, token)
|
||||||
--如果校验结果中的verified==false,则表示令牌无效
|
--如果校验结果中的verified==false,则表示令牌无效
|
||||||
if jwt_obj.verified == false then
|
if jwt_obj.verified == false then
|
||||||
response["code"] = 401
|
response["code"] = 401
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user