Nginx 通过 map 模块精确匹配 App 固定 User-Agent 格式(如 MyApp/4.1.0 (Android;...)),在 location 中用 return 403 拦截非合规请求,并可选增加 X-App-Verified 头校验提升安全性。

要让 Nginx 只允许特定移动端 App 访问接口,核心是**精准识别 App 自身发出的请求**,而不是泛泛拦截“所有手机浏览器”。关键在于利用 App 固定、可约定的 User-Agent 特征,配合轻量判断逻辑,避免误拦或绕过。
用 map 模块做 UA 精确匹配
不依赖 location 里写 if 判断,而是在 http 块中提前定义识别规则:
- 要求客户端统一 UA 格式,例如:MyApp/4.1.0 (Android; SM-G998B) 或 MyApp/4.1.0 (iOS; iPhone14,3)
- 在 http 块中配置 map,只对符合格式的 UA 设 $is_myapp = 1:
default 0;
"~*^MyApp/[0-9]+\.[0-9]+\.[0-9]+\s+\(Android;" 1;
"~*^MyApp/[0-9]+\.[0-9]+\.[0-9]+\s+\(iOS;" 1;
}
后续可在 location 中直接使用该变量,逻辑清晰、性能高、无嵌套风险。
在接口 location 中强制校验
对目标 API 路径(如 /api/v1/),只放行 $is_myapp = 1 的请求:
- 用 return 403 快速拦截不合规请求,不进入后端
- 不推荐用 if ($is_myapp = 0) { deny all; } —— deny 在 location 内部不支持变量,语义也不如 return 明确
if ($is_myapp = 0) {
return 403;
}
proxy_pass http://backend-api;
}
注意:此处 if 仅作单条件判断,不拼接、不嵌套,Nginx 官方接受这种用法。
增强可靠性:加 Header 校验(可选)
仅靠 UA 有一定被伪造风险。若 App 可配合改造,建议增加自定义请求头:
- App 请求时固定携带 X-App-Verified: true
- Nginx 配合验证:if ($http_x_app_verified != "true") { return 403; }
- 比 UA 更难伪造,且不依赖字符串解析,判断更快
该方式适合已有 SDK 控制力的场景,不增加额外鉴权服务负担。
不建议的做法
以下方式容易出问题,应避免:
- 在 server 或 location 中用大量 if 匹配 UA 正则——易错、难维护、性能差
- 仅靠 “mobile”、“android” 等模糊关键词识别——微信内置浏览器、QQ 浏览器也会命中,导致误拦
- 把 allow/deny 用在 UA 控制上——allow/deny 只认 IP,不支持字符串条件
- 在 upstream 或 http 全局块写访问控制逻辑——作用域错误,不生效


















