Nginx可通过map指令结合$date_local、$time_iso8601等时间变量实现基于时间的动态访问控制,推荐使用OpenResty+Lua解析时间或cron生成标记文件配合try_files方案。
可以通过 Nginx 的
指令结合系统时间变量(如
、
)实现基于时间的动态访问控制,无需外部脚本或模块。核心是将时间特征映射为布尔标记,再在
或
块中用
或
等方式生效。
提取可判断的时间维度
Nginx 内置变量支持按需截取时间片段。例如:
格式为
,适合做日期范围控制(如只允许工作日)
同样为
,适用于 UTC 场景
是完整 ISO 时间(如
),可用
提取小时、星期等
注意:
和
是只读变量,每秒更新一次;不支持直接正则匹配,需配合
使用。
用 map 构建时间策略开关
在
块中定义时间映射规则。例如限制仅在工作日 9:00–18:00 开放后台接口:
⚠️ 实际中,Nginx 原生不支持从
中直接提取星期几或小时。推荐方案是:
使用
OpenResty + Lua
:调用
解析
,返回
、
等
或用
配合
和固定时间段(如屏蔽周末):通过预设周末日期列表做字符串匹配
结合 if 或 auth_request 执行拦截
定义好时间标记后,在
中应用:
更健壮的做法是用
将鉴权逻辑分离(例如由一个内部 /time-check 接口返回 200/403),避免
在 location 中的限制问题。
替代方案:用 cron + 文件标记 + nginx 内部变量
若无法引入 Lua,可借助系统定时任务生成时间标记文件:
cron 每分钟检查当前时间,写入
(存在表示允许)
Nginx 用
+
判断该文件是否存在
示例:
,配合外部脚本维护
该方式简单可靠,适合对实时性要求不苛刻(如分钟级精度)且不允许扩展模块的环境。
不复杂但容易忽略:Nginx 时间变量是 worker 进程启动时初始化、每秒刷新一次,不是每次请求实时计算;高精度时段控制(如秒级)必须依赖外部服务或 Lua。
map$date_local$time_iso8601locationserverifauth_request$date_localYYYYMMDD$date_gmtYYYYMMDD$time_iso86012024-06-15T14:30:22+08:00map$date_local$date_gmtmaphttpmap $date_local $is_workday {
default 0;
~^(?:202[0-9]{5}|203[0-9]{5})$ 1; # 粗略匹配年月日格式(实际需更精确)
}
更可靠的方式:用 $time_iso8601 提取星期和小时
map $time_iso8601 $weekday {
"~^....-..-..T..:..:..(+[0-9]{4})?$" $1; # 实际不可取 —— 正确做法是用 Lua 或外部服务
}
$time_iso8601os.datengx.var.time_iso8601hourwdaymap$date_locallocationlocation /admin/ {
# 假设已用 map 定义了 $allowed_hour(值为 1 或 0)
if ($allowed_hour = 0) {
return 403 "Access denied outside business hours";
}
proxy_pass http://backend;
}auth_requestif/tmp/allow_adminmaptry_filesmap "" $can_access_admin { default 0; include /tmp/allow_admin_map; }/tmp/allow_admin_map