lolly/docs/config/lua/access-by-lua.conf
xfy 6543422281 docs: 添加 Nginx 配置和 Lua 脚本示例文档
- config: 反向代理、缓存、负载均衡、安全、SSL 等配置模板
- lua: API 网关、认证、动态路由、限流、WebSocket 等脚本示例

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 17:59:22 +08:00

134 lines
4.1 KiB
Plaintext

# ============================================================
# 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 异步调用