FastCGI不处理防盗链或访问控制,需由Nginx在转发前完成;应于location块中配置Referer白名单、Token签名校验(secure_link)、IP+UA限制及Cookie会话校验等多重防护措施。

FastCGI 本身不处理防盗链或访问控制,这些逻辑必须由 Nginx 在转发请求前完成。关键在于:Nginx 要在 location ~ \.php$ 或其他动态接口匹配块中,插入校验逻辑,拦截非法请求,避免将恶意流量透传给 PHP-FPM。
Referer 白名单(基础防护)
适用于内部系统跳转、管理后台等可控场景。Nginx 利用 valid_referers 检查来源页面是否可信:
- 配置示例:
location ~ ^/api/v1/(download|report)\.php$ { valid_referers none blocked *.mycompany.com myapp.internal; if ($invalid_referer) { return 403; } include fastcgi_params; fastcgi_pass php_backend; } -
none允许直接访问(如浏览器地址栏输入);blocked允许 Referer 被移除或被防火墙过滤的情况;server_names后跟域名支持通配符(如*.mycompany.com) - 注意:HTTPS 页面引用 HTTP 资源时 Referer 可能被浏览器清空,微信内嵌页、PWA 等环境也常失效,不能单独依赖
Token 签名校验(推荐主力方案)
对每个 API 请求强制携带时效性签名,服务端与 Nginx 共享密钥,无需回源即可完成验证,适合下载链接、导出接口、敏感数据获取等场景:
- 客户端生成 URL 示例:
/api/v1/export.php?file=20260903.xlsx&t=1725381180&e=600&md5=9a3f7c1b...
其中t是 Unix 时间戳,e是过期秒数(如 600 表示 10 分钟),md5是$uri$t$e$secret_key的 MD5 值 - Nginx 配置(需启用
ngx_http_secure_link_module):location ~ ^/api/v1/export\.php$ { secure_link $arg_t,$arg_e; secure_link_md5 "$uri$arg_t$arg_e$SECRET_KEY"; if ($secure_link = "") { return 403; } if ($secure_link = "0") { return 410; } include fastcgi_params; fastcgi_pass php_backend; } -
$secure_link = ""表示签名无效或过期;= "0"表示时间已过(t+e < now)
IP + User-Agent 组合限制(增强可信度)
针对固定调用方(如内部运维脚本、第三方合作系统),可叠加 IP 和 UA 校验,降低重放和伪造风险:
- 只允许指定 IP 段且 UA 包含特定标识的请求:
location ~ ^/api/v1/internal/.*\.php$ { allow 10.10.20.0/24; allow 172.16.5.100; deny all; <pre class='brush:php;toolbar:false;'>if ($http_user_agent !~ "^MyInternalTool\/[0-9]+\.[0-9]+$") { return 403; } include fastcgi_params; fastcgi_pass php_backend;}
- 注意:
$http_user_agent区分大小写,建议用~*忽略大小写;UA 易伪造,仅作辅助判断,不可替代 Token 或身份认证
结合后端 Session 或 JWT Cookie(会话级控制)
当接口要求用户已登录时,应校验 Cookie 中的有效凭证,而非仅靠前端传参:
- Nginx 提取并简单校验 Cookie 存在性与格式(深度校验交由后端):
location ~ ^/api/v1/user/.*\.php$ { if ($http_cookie !~ "PHPSESSID=[a-zA-Z0-9]{26,}") { return 401; } # 或校验 JWT 格式(如 Base64URL 编码的三段式) if ($http_cookie !~ "auth_token=eyJhbGciOi[^\;]+") { return 401; } include fastcgi_params; fastcgi_pass php_backend; } - 更严谨的做法是使用
auth_request模块,将 Cookie 交给一个专用鉴权子请求(如 /auth)验证,返回 200 才放行,实现与业务逻辑解耦


















