auth_request模块通过子请求交由外部服务完成认证,仅依据其返回的200/401/403状态码决定放行或拒绝,并透传响应头供后续使用。

auth_request 模块的作用与工作原理
auth_request 模块本身不处理认证逻辑,它只是把请求“转发”给一个指定的内部子请求(location),等待该子请求返回 HTTP 200 才放行原请求;若返回 401/403,则直接拒绝访问。这个设计非常轻量,把鉴权决策完全交给外部服务——比如你自己的 OAuth2 校验服务、Keycloak、Auth0 或自建的 token 解析接口。
关键点:Nginx 不解析 JWT、不验证签名、不查用户角色,它只相信你那个子请求的 HTTP 状态码和响应头(如 X-User-ID、X-Scopes)。
前置准备:OAuth2 授权服务需提供校验端点
你需要一个能接收 Bearer Token 并完成以下动作的服务:
- 从 Authorization: Bearer
中提取 token - 校验签名(RSA/HS256)、过期时间、issuer、audience
- 可选:解析 claims(如 scope、roles、groups),做细粒度判断
- 成功则返回 200 OK,并带上必要头信息(如 X-User-ID: alice);失败返回 401 或 403
例如用 Python Flask 快速写一个校验接口(仅示意):
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/oauth2/token/validate')
def validate():
auth = request.headers.get('Authorization')
if not auth or not auth.startswith('Bearer '):
return '', 401
token = auth[7:]
# 这里调用 PyJWT 验证 + scope 检查
if is_valid_and_authorized(token, required_scope='api:read'):
return '', 200, {'X-User-ID': 'alice', 'X-Scopes': 'api:read api:write'}
return '', 403
Nginx 配置 auth_request 的核心步骤
在 server 或 location 块中启用 auth_request,注意三点:子请求地址、透传 Authorization 头、接收上游头信息。
- 定义一个内部 location(如 /_validate),指向你的 OAuth2 校验服务
- 在目标 location(如 /api/)中添加 auth_request /_validate
- 用 auth_request_set 提取子请求响应头,供后续使用(如记录日志、透传给后端)
- 确保子请求能收到原始请求的 Authorization 头 —— 默认不透传,需显式配置 proxy_pass_request_headers on 和 proxy_set_header Authorization $http_authorization
示例配置片段:
location = /_validate {
internal;
proxy_pass https://auth-service.example.com/oauth2/token/validate;
proxy_pass_request_headers on;
proxy_set_header Host auth-service.example.com;
proxy_set_header Authorization $http_authorization;
proxy_set_header X-Original-URI $request_uri;
}
location /api/ {
auth_request /_validate;
auth_request_set $user_id $upstream_http_x_user_id;
auth_request_set $scopes $upstream_http_x_scopes;
proxy_pass http://backend;
proxy_set_header X-Auth-User $user_id;
proxy_set_header X-Auth-Scopes $scopes;
}
进阶技巧:组合 scope 控制与 fallback 处理
auth_request 只管“是否放行”,但你可以用 map + if(谨慎)或 OpenResty/Lua 做更灵活的控制。不过纯 Nginx 下仍有实用方案:
- 让校验服务根据 scope 返回不同状态码:403 表示 token 有效但权限不足,Nginx 可配 error_page 403 /403.html
- 用 auth_request_recursive on 支持嵌套校验(如先验 token,再查 RBAC),但需注意循环风险
- 配合 limit_req 或 geo 模块,在 auth_request 放行后做二次限流或区域限制
- 调试时开启 auth_request_log 和 error_log debug,查看子请求的完整交互
真实场景中,建议把 token 校验和 scope 判断全部下沉到 /_validate 接口,保持 Nginx 配置简洁、可维护。











