如何通过Nginx获取JWT令牌以实现Authentik反向代理认证
自动获取JWT令牌并完成Nginx Proxy Manager认证的方案
针对你的场景,标准Nginx无法直接实现自动获取和刷新JWT令牌,需要借助**OpenResty(带Lua扩展的Nginx)**来实现令牌的自动获取、缓存与刷新逻辑。以下是具体实现步骤:
1. 准备工作:安装OpenResty
如果当前使用的是普通Nginx,建议替换为OpenResty(内置Lua模块,无需额外编译);若已使用Nginx Proxy Manager,可确保其支持Lua扩展(部分预编译版本已包含,或需自行编译)。
2. 编写Lua令牌管理脚本
创建fetch_jwt.lua脚本,实现令牌的获取、缓存和自动刷新:
local http = require "resty.http" local cjson = require "cjson" -- 共享字典:用于缓存JWT令牌,需在Nginx配置中提前声明 local jwt_cache = ngx.shared.jwt_cache -- 从认证接口获取新令牌 local function get_new_token() local httpc = http.new() local res, err = httpc:request_uri("http://localhost:81/api/tokens", { method = "POST", headers = { ["Content-Type"] = "application/json; charset=UTF-8" }, body = cjson.encode({ identity = "[你的邮箱]", secret = "[你的密钥]" }) }) if not res then ngx.log(ngx.ERR, "获取JWT令牌失败: ", err) return nil end if res.status ~= 200 then ngx.log(ngx.ERR, "令牌请求返回异常状态码: ", res.status) return nil end local data = cjson.decode(res.body) local token = data.token -- 需匹配接口返回的令牌字段名 local expires_in = data.expires_in or 86400 -- 默认24小时,根据实际返回调整 -- 缓存令牌,提前300秒过期触发刷新,避免令牌失效 jwt_cache:set("auth_token", token, expires_in - 300) return token end -- 优先从缓存取令牌,缓存失效则获取新令牌 local token = jwt_cache:get("auth_token") if not token then token = get_new_token() if not token then ngx.exit(ngx.HTTP_UNAUTHORIZED) -- 令牌获取失败时返回401 end end -- 设置请求头的Authorization字段 ngx.req.set_header("Authorization", "Bearer " .. token)
3. 配置Nginx(或Nginx Proxy Manager自定义配置)
3.1 在HTTP块添加共享字典声明
在Nginx主配置的http块中添加,用于存储令牌缓存:
http { ... lua_shared_dict jwt_cache 1m; -- 分配1MB内存用于缓存令牌 ... }
3.2 在代理Location中引入Lua脚本
在需要认证的代理路径配置中,添加access_by_lua_file指令,让请求先执行令牌获取逻辑:
location /你的代理路径 { -- 执行令牌获取脚本 access_by_lua_file /usr/local/openresty/nginx/conf/fetch_jwt.lua; -- 替换为实际脚本路径 -- 原有代理配置 proxy_set_header Host $host; proxy_pass http://你的上游服务地址; }
关键说明
- 手动配置失败的可能原因:手动生成的JWT格式不符合接口要求、令牌已过期,或Nginx Proxy Manager的GUI配置覆盖了自定义的
proxy_set_header指令。 - 安全优化:建议将邮箱和密钥通过环境变量传入脚本(如
os.getenv("NPM_JWT_IDENTITY")),避免硬编码敏感信息。 - 刷新逻辑:脚本会在令牌即将过期前自动重新获取,确保请求始终携带有效令牌。
内容的提问来源于stack exchange,提问作者Asem Khen
相关产品推荐
相关产品推荐

