Skip to content

Commit

Permalink
feat(config): codo gateway 支持注入环境变量 支持 数组注入 使用 (,) 分割的数组
Browse files Browse the repository at this point in the history
  • Loading branch information
Ccheers committed Jun 12, 2024
1 parent b84ae5a commit 425e6d8
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 75 deletions.
30 changes: 9 additions & 21 deletions conf/app.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
"token_secret": "xxxxxx"
},
"sso2internal": {
"sso_token_secret": "xxxxxx",
"sso_token_secret": "xxxxxx",
"sso_jwt_key": "sso_token",
"internal_token_secret": "xxxxxx",
"internal_token_secret": "xxxxxx",
"internal_jwt_key": "auth_key"
},
"mfa": {
"mfa_secret": "xxxxxx",
"mfa_secret": "xxxxxx",
"mfa_key": "mfa_key"
},
"plugins": [
Expand Down Expand Up @@ -51,23 +51,11 @@
},
"admin": {
"jwt_secret": "xxxxxx",
"account": {
"admin": {
"password": "tainiubile",
"info": {
"roles": [
"admin"
],
"introduction": "I am a super administrator",
"avatar": "https://xxx.com/1.gif",
"name": "管理员"
}
}
}
"accounts": [
"用户名1"
]
},
"tokens": {
"xxx": {
"desc": "系统默认 api token"
}
}
"tokens": [
"api_token_xxxx"
]
}
31 changes: 29 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,35 @@ services:
restart: unless-stopped
build: .
environment:
- "CODO_GATEWAY.appName=cctest"
- "CODO_GATEWAY.admin.account.admin.info.roles.1=cctest"
- "CODO_GATEWAY.admin.accounts=cctest"
- "CODO_GATEWAY.appName=cctest_api-gateway"
- "CODO_GATEWAY.env=cctest_test"
- "CODO_GATEWAY.etcd.http_host=http://127.0.0.1:2379"
- "CODO_GATEWAY.etcd.data_prefix=/my/gw/cctest"
- "CODO_GATEWAY.jwt_auth.key=cctest_auth_key"
- "CODO_GATEWAY.jwt_auth.token_secret=cctest_xxxxx"
- "CODO_GATEWAY.codo_rbac.key=cctest_auth_key"
- "CODO_GATEWAY.codo_rbac.token_secret=cctest_xxxx"
- "CODO_GATEWAY.sso2internal.sso_token_secret=cctest_xxxxxx"
- "CODO_GATEWAY.sso2internal.sso_jwt_key=cctest_sso_token"
- "CODO_GATEWAY.sso2internal.internal_token_secret=cctest_xxxx"
- "CODO_GATEWAY.sso2internal.internal_jwt_key=cctest_auth_key"
- "CODO_GATEWAY.mfa.mfa_secret=cctest_xxxxxx"
- "CODO_GATEWAY.mfa.mfa_key=cctest_mfa_key"
- "CODO_GATEWAY.plugins_config.redis-logger.host=127.0.0.2"
- "CODO_GATEWAY.plugins_config.redis-logger.port=6379"
- "CODO_GATEWAY.plugins_config.redis-logger.auth_pwd=1234567"
- "CODO_GATEWAY.plugins_config.redis-logger.db=2"
- "CODO_GATEWAY.plugins_config.redis-logger.alive_time=604801"
- "CODO_GATEWAY.plugins_config.redis-logger.channel=cctest_gw"
- "CODO_GATEWAY.plugins_config.redis-logger.full_log=cctest_no"
- "CODO_GATEWAY.admin.jwt_secret=cctest_xxxxx"
- "CODO_GATEWAY.admin.account.admin.password=cctest_tainiubile"
- "CODO_GATEWAY.admin.account.admin.info.introduction=cctest_I am a super administrator"
- "CODO_GATEWAY.admin.account.admin.info.avatar=https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafecctest.gif"
- "CODO_GATEWAY.admin.account.admin.info.name=cctest_管理员"
- "CODO_GATEWAY.tokens=e09d6153f1c15395397be3639d14479"
- "CODO_GATEWAY.plugins=default_plugin,discovery_plugin,tracing_plugin,rewrite_plugin,jwt_plugin,codo_rbac_plugin,kafka-logger,redis-logger,limit-req,referer-restriction,ip-restriction,cors_plugin,sso2internal"
ports:
- "8888:8888"
- "11000:11000"
29 changes: 25 additions & 4 deletions gateway/admin/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,15 @@ local function check_api_token()
log.debug("no api token settings")
return false
end
if not tokens[token] then

local in_tokens = false
for _, tk in pairs(tokens) do
if token == tk then
in_tokens = true
break
end
end
if not in_tokens then
return false
end
log.debug("api token auth: ", token)
Expand All @@ -102,7 +110,7 @@ local function check_token()
end

local jwt_secret = config_get("admin").jwt_secret
local account = config_get("admin").account
local accounts = config_get("admin").accounts

local session = jwt:verify(jwt_secret, token)

Expand All @@ -116,10 +124,23 @@ local function check_token()
username = session.payload.data.username
end

if not username or not account[username] then
if not username then
resp.exit(ngx.HTTP_INTERNAL_SERVER_ERROR, "用户不存在")
end
local login_user = account[username].info

local in_admin = false
for _, account_name in pairs(accounts) do
if account_name == username then
in_admin = true
break
end
end

if not in_admin then
resp.exit(ngx.HTTP_INTERNAL_SERVER_ERROR, "用户不存在")
end

local login_user = {}
login_user.username = username
ngx.ctx.admin_login_user = login_user
end
Expand Down
30 changes: 1 addition & 29 deletions gateway/admin/login.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,7 @@ local config_get = require("app.config").get
local resp = require("app.core.response")

local function login()
local jwt_secret = config_get("admin").jwt_secret
local account = config_get("admin").account
local body = ngx.req.get_body_data()
if not body then
resp.exit(ngx.HTTP_INTERNAL_SERVER_ERROR, "用户名或密码为空")
end

local data = cjson.decode(ngx.req.get_body_data())

if not data or not data.username or not data.password then
resp.exit(ngx.HTTP_INTERNAL_SERVER_ERROR, "用户名或密码为空")
end

local user = account[data.username]
if not user or user.password ~= data.password then
resp.exit(ngx.HTTP_INTERNAL_SERVER_ERROR, "用户名或密码错误")
end

update_time()
local token = jwt:sign(jwt_secret,
{
header = {typ = "JWT", alg = "HS256"},
payload = {
exp = now() + 7 * 24 * 60 + 60,
username = data.username
}
}
)
resp.exit(ngx.OK, {token = token})
resp.exit(ngx.HTTP_INTERNAL_SERVER_ERROR, "请从 codo 统一认证登陆")
end

local function info()
Expand Down
60 changes: 41 additions & 19 deletions gateway/app/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ local json = require("app.core.json")
local str_utils = require("app.utils.str_utils")
local ngx_config = ngx.config
local error = error
local pairs = pairs
local os = os

local _M = {}

Expand Down Expand Up @@ -59,37 +61,57 @@ local app_config = {
},
admin = {
jwt_secret = "xxxx",
account = {
admin = {
password = "tainiubile",
info = {
roles = { "admin" },
introduction = "I am a super administrator",
avatar = "https://xxx.com/1.gif",
name = "管理员"
}
}
}
accounts = { "admin" }
},
tokens = {
["xxx"] = {
desc = "系统默认 api token"
}
}
tokens = { "api_token_xxxx" }
}

local function splitStringByComma(inputString)
local result = {}
for match in (inputString .. ','):gmatch("(.-),") do
table.insert(result, match)
end
return result
end

local function is_array(t)
local maxIndex = 0
local count = 0

for k, _ in pairs(t) do
if type(k) == "number" then
maxIndex = math.max(maxIndex, k)
count = count + 1
else
return false -- 存在非数字键,认为是map
end
end

-- 键为连续的数字,认为是数组
return maxIndex == count
end

-- 用于递归地检查配置表并使用环境变量更新
local function update_config_with_env(config, parent_key)
for k, v in pairs(config) do
local env_key = parent_key and (parent_key .. "." .. k) or k
if type(v) == "table" then
-- 递归处理嵌套表
config[k] = update_config_with_env(v, env_key)
if is_array(v) then
-- 尝试从环境变量中获取新的配置值
local env_value = os.getenv(env_key)
if env_value then
print("load from env === ", env_key, " env === ", env_value)
config[k] = splitStringByComma(env_value)
end
else
-- 递归处理嵌套表
config[k] = update_config_with_env(v, env_key)
end
else
-- 尝试从环境变量中获取新的配置值
local env_value = os.getenv(env_key)
print("env_key======", env_key)
if env_value then
print("load from env === ", env_key, " env === ", env_value)
config[k] = env_value
end
end
Expand Down

0 comments on commit 425e6d8

Please sign in to comment.