与许多应用程序一样,我有一些比其他端点更敏感的端点,例如登录和密码重置,并且需要速率限制。但是,nginx 通过代理 PHP-FPM 的标准位置处理程序处理所有 PHP 资源请求:
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_pass php80;
}
这意味着我不能使用location
指令来匹配我的敏感端点,因为它会阻止它们被传递给 PHP。
例如,如果我定义一个速率限制并将其用于登录 URL 的位置:
limit_req_zone $binary_remote_addr zone=sensitive:2m rate=3r/m;
location /login {
limit_req zone=sensitive burst=3 nodelay;
}
它将对该端点的请求进行速率限制,但它们将不再由 PHP 处理。
我可以做一个愚蠢的复制/粘贴,并在每个端点上做这样的事情:
location /login {
limit_req zone=sensitive burst=3 nodelay;
try_files $uri =404;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_pass php80;
}
但我确信还有更好的方法。
我应该如何在 PHP 位置指令中定义速率限制?
答案1
我所做的是将样板移至服务器块,然后将其保留fastcgi_pass
在 each 中location
。类似这样的操作应该可以工作:
server {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_index index.php;
include fastcgi_params;
location /login {
limit_req zone=sensitive burst=3 nodelay;
fastcgi_pass php80;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass php80;
}
}
小心:确保检查“敏感”location
是否确实与更高优先级匹配。类似的东西location /login.php
可能会被覆盖location ~ \.php$
。在这种情况下,请使用location = /login.php
。