# ============================================================ # Nginx access_by_lua 认证配置示例 # ============================================================ # # 功能说明: # - 使用 Lua 实现访问控制 # - JWT 验证 # - 自定义认证逻辑 # # Lolly 对应配置: # 可通过 Lua 沙箱实现自定义认证中间件 # ============================================================ http { lua_shared_dict tokens 10m; server { listen 80; server_name auth-lua.example.com; # JWT 认证 location /api { access_by_lua_block { local jwt = require "resty.jwt" -- 获取 Authorization 头 local auth_header = ngx.var.http_authorization if not auth_header then ngx.status = 401 ngx.header["WWW-Authenticate"] = 'Bearer realm="API"' ngx.say('{"error": "Missing authorization header"}') ngx.exit(401) end -- 解析 Bearer token local _, _, token = string.find(auth_header, "Bearer%s+(.+)") if not token then ngx.status = 401 ngx.say('{"error": "Invalid token format"}') ngx.exit(401) end -- 验证 JWT local jwt_obj = jwt:verify("secret-key", token) if not jwt_obj.verified then ngx.status = 401 ngx.say('{"error": "Invalid token"}') ngx.exit(401) end -- 将用户信息传递给后端 ngx.req.set_header("X-User-ID", jwt_obj.payload.sub) ngx.req.set_header("X-User-Role", jwt_obj.payload.role) } proxy_pass http://backend:8080; } # API Key 认证 location /api/v2 { access_by_lua_block { local api_key = ngx.var.http_x_api_key if not api_key then ngx.status = 401 ngx.say('{"error": "Missing API key"}') ngx.exit(401) end -- 从共享字典验证 API key local tokens = ngx.shared.tokens local user_id = tokens:get(api_key) if not user_id then ngx.status = 401 ngx.say('{"error": "Invalid API key"}') ngx.exit(401) end ngx.req.set_header("X-User-ID", user_id) } proxy_pass http://backend:8080; } # IP 白名单 + Token 认证 location /admin { access_by_lua_block { local ip = ngx.var.remote_addr -- IP 白名单检查 local whitelist = { ["127.0.0.1"] = true, ["10.0.0.0/8"] = true, -- 需要额外处理 CIDR } if not whitelist[ip] then -- 非 IP 白名单,需要 Token local token = ngx.var.http_x_admin_token if not token or token ~= "admin-secret" then ngx.status = 403 ngx.say('{"error": "Access denied"}') ngx.exit(403) end end } proxy_pass http://admin-backend:8080; } } } # access_by_lua 说明: # # 1. 执行时机: # - 在 rewrite 阶段之后 # - 在 content 阶段之前 # - 可用于访问控制 # # 2. 常用操作: # - ngx.exit(status): 终止请求,返回状态码 # - ngx.say(body): 输出响应体 # - ngx.req.set_header(): 设置请求头 # - ngx.req.get_headers(): 获取请求头 # # 3. 认证模式: # - JWT: 解析验证 JWT token # - API Key: 从共享字典验证 # - Basic Auth: 自定义验证逻辑 # - OAuth: 调用外部服务验证 # # 4. 性能优化: # - 使用共享字典缓存验证结果 # - 避免每次请求都访问外部服务 # - 使用 cosocket 异步调用