如何在Lua脚本中验证Kong许可证过期日期与当前日期?
在Kong中用Lua实现许可证过期校验
嘿,刚接触Lua和Kong的话,这个需求其实挺好上手的——核心就是把许可证的过期日期转换成时间戳,再和当前时间戳对比就行。咱们一步步来,结合Kong的插件环境实现:
1. 核心思路:时间戳对比
Lua里的os.time()能把日期转换成 Unix 时间戳(从1970年至今的秒数),用时间戳做对比是最靠谱的,避免字符串格式不一致或者时区的坑。
2. 编写日期解析函数
首先写个辅助函数,把许可证的过期日期字符串转成时间戳。假设你的过期日期是YYYY-MM-DD格式(比如2024-12-31),如果是其他格式(比如ISO 8601带UTC),可以调整正则匹配:
local function parse_expiry_date(expiry_str) -- 匹配YYYY-MM-DD格式的日期 local year, month, day = expiry_str:match("(%d%d%d%d)-(%d%d)-(%d%d)") if not year then return nil, "Invalid date format. Please use YYYY-MM-DD." end -- 把日期设置为当天的最后一秒,避免当天过期但白天访问就被拦截的情况 return os.time({ year = tonumber(year), month = tonumber(month), day = tonumber(day), hour = 23, min = 59, sec = 59 }) end
如果你的许可证日期是UTC格式(比如2024-12-31T23:59:59Z),可以用这个版本的解析函数:
local function parse_utc_expiry_date(expiry_str) local year, month, day, hour, min, sec = expiry_str:match("(%d%d%d%d)-(%d%d)-(%d%d)T(%d%d):(%d%d):(%d%d)Z") if not year then return nil, "Invalid UTC date format. Please use YYYY-MM-DDTHH:MM:SSZ." end -- 生成UTC时间戳,避免时区差异 return os.time({ year = tonumber(year), month = tonumber(month), day = tonumber(day), hour = tonumber(hour), min = tonumber(min), sec = tonumber(sec), isdst = false -- 禁用夏令时,确保是UTC时间 }) end
3. 结合Kong插件实现校验
Kong的插件通常在access阶段做请求前校验,这里写一个完整的插件示例:
local plugin = { PRIORITY = 1000, -- 优先级越高,插件越先执行(确保在其他业务插件前做校验) VERSION = "0.1.0" } -- 辅助函数:解析过期日期(这里用YYYY-MM-DD格式) local function parse_expiry_date(expiry_str) local year, month, day = expiry_str:match("(%d%d%d%d)-(%d%d)-(%d%d)") if not year then return nil, "Invalid date format. Please use YYYY-MM-DD." end return os.time({ year = tonumber(year), month = tonumber(month), day = tonumber(day), hour = 23, min = 59, sec = 59 }) end function plugin:access(plugin_conf) -- 1. 获取许可证过期日期:这里假设从插件配置中读取(你也可以从请求头、数据库等地方获取) local expiry_date_str = plugin_conf.license_expiry_date if not expiry_date_str then kong.response.exit(403, {message = "License information missing."}) return end -- 2. 解析过期日期为时间戳 local expiry_timestamp, err = parse_expiry_date(expiry_date_str) if not expiry_timestamp then kong.response.exit(400, {message = err}) return end -- 3. 获取当前时间戳(如果是UTC场景,用os.time(os.date("!*t"))获取UTC时间戳) local current_timestamp = os.time() -- 4. 对比时间戳,判断是否过期 if expiry_timestamp <= current_timestamp then kong.response.exit(403, {message = "License has expired. Please renew to continue service."}) return end -- 5. 校验通过,继续处理请求 kong.log.info("License is valid. Expires on: ", expiry_date_str) end return plugin
4. 关键注意事项
- 时区问题:如果你的许可证日期是UTC,一定要用UTC时间戳对比,否则服务器本地时区和UTC不一致会导致校验错误。可以用
os.time(os.date("!*t"))获取当前UTC时间戳。 - 日期来源:示例中从插件配置读取过期日期,你也可以根据实际需求改成从请求头(比如
X-License-Expiry)、JWT Token的claim里,或者数据库查询获取。 - 错误处理:根据你的业务需求调整错误码和提示信息,比如过期返回403,格式错误返回400,缺少信息返回403等。
内容的提问来源于stack exchange,提问作者venkat
相关产品推荐
相关产品推荐

