add Refresh
This commit is contained in:
+80
-152
@@ -1,183 +1,111 @@
|
||||
local core = require("apisix.core")
|
||||
local redis = require("resty.redis")
|
||||
|
||||
local _M = {}
|
||||
|
||||
function _M.access(conf, ctx)
|
||||
-- 确保在请求阶段执行
|
||||
if not ngx or not ngx.var then
|
||||
core.log.warn("Not in request context, skipping auth check")
|
||||
return
|
||||
end
|
||||
|
||||
-- ========== 获取请求头 ==========
|
||||
local headers = ngx.req.get_headers()
|
||||
local user_key = headers["Authorization"]
|
||||
local service_code = headers["Authorization-Type"]
|
||||
local req_auth = headers["Authorization-Auth"]
|
||||
local refresh = headers["Refresh"]
|
||||
local request_uri = ngx.var.uri
|
||||
core.log.info("REQUEST_DEBUG: uri = "..request_uri)
|
||||
|
||||
-- ========== 获取 Redis 配置 ==========
|
||||
local redis_config = core.config.local_conf().redis or {}
|
||||
local redis_host = redis_config.host or "127.0.0.1"
|
||||
local redis_port = redis_config.port or 6379
|
||||
local redis_password = redis_config.password or ""
|
||||
local redis_db = redis_config.db or 0
|
||||
local white_list = {
|
||||
["/api/v3/login"] = true,
|
||||
["/admin/v3/login"] = true,
|
||||
["/admin/v3/refresh"] = true,
|
||||
}
|
||||
|
||||
-- ========== 参数校验 ==========
|
||||
if not user_key or user_key == "" then
|
||||
core.log.warn("Missing Authorization header")
|
||||
return core.response.exit(401, {
|
||||
code = 10003,
|
||||
message = "未登录",
|
||||
data = nil
|
||||
})
|
||||
end
|
||||
local user_key = core.request.header(ctx, "authorization")
|
||||
local service_code = core.request.header(ctx, "authorization-type")
|
||||
local req_auth = core.request.header(ctx, "authorization-auth")
|
||||
local refresh = core.request.header(ctx, "refresh")
|
||||
core.log.info("RAW_HEADER_DEBUG: refresh=["..(refresh or "").."], service_code=["..(service_code or "").."], token=["..(user_key or "").."]")
|
||||
|
||||
if not service_code or service_code == "" then
|
||||
core.log.warn("Missing Authorization-Type header")
|
||||
return core.response.exit(401, {
|
||||
code = 10003,
|
||||
message = "未登录",
|
||||
data = nil
|
||||
})
|
||||
end
|
||||
local skip_auth = white_list[request_uri]
|
||||
if skip_auth then
|
||||
core.log.info("WHITE_LIST_DEBUG: hit white list "..request_uri)
|
||||
-- 白名单只标记,不return,不再此处set_header
|
||||
else
|
||||
-- 非白名单完整鉴权逻辑
|
||||
if not user_key or user_key == "" then
|
||||
return core.response.exit(401, {code = 10003, message = "未登录"})
|
||||
end
|
||||
if not service_code or service_code == "" then
|
||||
return core.response.exit(401, {code = 10003, message = "未登录"})
|
||||
end
|
||||
|
||||
-- ========== 构建Redis Key ==========
|
||||
local redis_key = "login:service:" .. service_code .. ":" .. user_key
|
||||
local redis_config = core.config.local_conf().redis or {}
|
||||
local redis_host = redis_config.host or "127.0.0.1"
|
||||
local redis_port = redis_config.port or 6379
|
||||
local redis_password = redis_config.password or ""
|
||||
local redis_db = redis_config.db or 0
|
||||
|
||||
-- ========== Redis连接 ==========
|
||||
local red = redis:new()
|
||||
red:set_timeouts(1000, 1000, 1000)
|
||||
|
||||
local ok, err = red:connect(redis_host, redis_port)
|
||||
if not ok then
|
||||
core.log.error("Redis connect error: ", err)
|
||||
red:set_keepalive(10000, 100)
|
||||
return core.response.exit(500, {
|
||||
code = 10003,
|
||||
message = "系统错误,请稍后重试",
|
||||
data = nil
|
||||
})
|
||||
end
|
||||
|
||||
-- Redis认证
|
||||
if redis_password and redis_password ~= "" then
|
||||
local auth_ok, auth_err = red:auth(redis_password)
|
||||
if not auth_ok then
|
||||
core.log.error("Redis auth error: ", auth_err)
|
||||
local redis_key = "login:service:" .. service_code .. ":" .. user_key
|
||||
local red = redis:new()
|
||||
red:set_timeouts(1000, 1000, 1000)
|
||||
local ok, err = red:connect(redis_host, redis_port)
|
||||
if not ok then
|
||||
red:set_keepalive(10000, 100)
|
||||
return core.response.exit(500, {
|
||||
code = 10003,
|
||||
message = "系统错误,请稍后重试",
|
||||
data = nil
|
||||
})
|
||||
return core.response.exit(500, {code = 10003, message = "系统错误,请稍后重试"})
|
||||
end
|
||||
end
|
||||
|
||||
-- 选择数据库
|
||||
if redis_db and redis_db > 0 then
|
||||
red:select(redis_db)
|
||||
end
|
||||
|
||||
-- ========== 获取用户信息 ==========
|
||||
local res, err = red:get(redis_key)
|
||||
red:set_keepalive(10000, 100)
|
||||
|
||||
if err then
|
||||
core.log.error("Redis get error: ", err)
|
||||
return core.response.exit(500, {
|
||||
code = 10003,
|
||||
message = "系统错误,请稍后重试",
|
||||
data = nil
|
||||
})
|
||||
end
|
||||
|
||||
if not res or res == ngx.null then
|
||||
core.log.warn("User not found in redis, key: ", redis_key)
|
||||
return core.response.exit(401, {
|
||||
code = 10003,
|
||||
message = "未登录或登录已过期",
|
||||
data = nil
|
||||
})
|
||||
end
|
||||
|
||||
-- ========== 解析用户信息 ==========
|
||||
local json, decode_err = core.json.decode(res)
|
||||
if not json then
|
||||
core.log.error("JSON decode error: ", decode_err, " data: ", res)
|
||||
return core.response.exit(500, {
|
||||
code = 10003,
|
||||
message = "数据解析错误",
|
||||
data = nil
|
||||
})
|
||||
end
|
||||
|
||||
-- ========== Admin路径权限校验 ==========
|
||||
if service_code == "admin1" then
|
||||
if not req_auth or req_auth == "" then
|
||||
core.log.warn("Missing Authorization-Auth header for admin")
|
||||
return core.response.exit(403, {
|
||||
code = 10008,
|
||||
message = "没有权限访问该资源",
|
||||
data = nil
|
||||
})
|
||||
if redis_password ~= "" then
|
||||
local auth_ok, auth_err = red:auth(redis_password)
|
||||
if not auth_ok then
|
||||
red:set_keepalive(10000, 100)
|
||||
return core.response.exit(500, {code = 10003, message = "系统错误,请稍后重试"})
|
||||
end
|
||||
end
|
||||
if redis_db > 0 then
|
||||
red:select(redis_db)
|
||||
end
|
||||
|
||||
local roles = json.roles or {}
|
||||
local expect_path = roles[req_auth]
|
||||
|
||||
if not expect_path or expect_path == "" then
|
||||
core.log.error("Permission not found for auth: ", req_auth,
|
||||
" user_id: ", json.id, " roles: ", core.json.encode(roles))
|
||||
return core.response.exit(403, {
|
||||
code = 10008,
|
||||
message = "没有权限访问该资源",
|
||||
data = nil
|
||||
})
|
||||
local res, err = red:get(redis_key)
|
||||
red:set_keepalive(10000, 100)
|
||||
if err or res == ngx.null then
|
||||
return core.response.exit(401, {code = 10003, message = "未登录或登录已过期"})
|
||||
end
|
||||
local json, decode_err = core.json.decode(res)
|
||||
if not json then
|
||||
return core.response.exit(500, {code = 10003, message = "数据解析错误"})
|
||||
end
|
||||
|
||||
local full_expect_uri = "/" .. expect_path
|
||||
|
||||
if request_uri ~= full_expect_uri then
|
||||
local is_prefix_match = false
|
||||
if service_code == "admin1" then
|
||||
if not req_auth or req_auth == "" then
|
||||
return core.response.exit(403, {code = 10008, message = "没有权限访问该资源"})
|
||||
end
|
||||
local roles = json.roles or {}
|
||||
local expect_path = roles[req_auth]
|
||||
if not expect_path then
|
||||
return core.response.exit(403, {code = 10008, message = "没有权限访问该资源"})
|
||||
end
|
||||
local full_expect_uri = "/" .. expect_path
|
||||
local match = false
|
||||
if expect_path:sub(-1) == "*" then
|
||||
local base_path = expect_path:sub(1, -2)
|
||||
if request_uri:find(base_path, 1, true) == 1 then
|
||||
is_prefix_match = true
|
||||
local base = expect_path:sub(1, -2)
|
||||
if request_uri:find(base, 1, true) == 1 then
|
||||
match = true
|
||||
end
|
||||
end
|
||||
|
||||
if not is_prefix_match then
|
||||
core.log.error("URI mismatch - request: ", request_uri,
|
||||
" expected: ", full_expect_uri,
|
||||
" auth: ", req_auth,
|
||||
" user_id: ", json.id)
|
||||
return core.response.exit(403, {
|
||||
code = 10008,
|
||||
message = "没有权限访问该资源",
|
||||
data = nil
|
||||
})
|
||||
if request_uri ~= full_expect_uri and not match then
|
||||
return core.response.exit(403, {code = 10008, message = "没有权限访问该资源"})
|
||||
end
|
||||
end
|
||||
|
||||
if json.id then
|
||||
ngx.req.set_header("X-User-Id", tostring(json.id))
|
||||
end
|
||||
if json.name then
|
||||
ngx.req.set_header("X-User-Name", json.name)
|
||||
end
|
||||
if json.username then
|
||||
ngx.req.set_header("X-Username", json.username)
|
||||
end
|
||||
end
|
||||
|
||||
-- ========== 向下游透传用户信息 ==========
|
||||
if json.id then
|
||||
ngx.req.set_header("X-User-Id", tostring(json.id))
|
||||
end
|
||||
|
||||
if json.name then
|
||||
ngx.req.set_header("X-User-Name", json.name)
|
||||
end
|
||||
|
||||
if json.username then
|
||||
ngx.req.set_header("X-Username", json.username)
|
||||
end
|
||||
ngx.req.set_header("X-Refresh", refresh )
|
||||
|
||||
ngx.req.set_header("X-Service-Code", service_code)
|
||||
ngx.req.set_header("X-Refresh", refresh or "")
|
||||
ngx.req.set_header("X-Service-Code", service_code or "")
|
||||
core.log.info("FINAL_SET_HEADER: X-Refresh=["..(refresh or "").."]")
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user