我需要根据2个条件在nginx中应用速率限制:
1。这无法检测发布请求中的_api密钥:
limit_req_zone "$arg__api" zone=api_zone:10m rate=30r/m;
limit_req zone=api_zone burst=10 nodelay;
2。这可以检测POST方法:
map $request_method $limit {
default "";
POST $binary_remote_addr;
}
limit_req_zone $limit zone=my_zone:10m rate=20r/m;
limit_req zone=my_zone burst=10 nodelay;
那么我怎样才能检测到它是POST并且帖子包含_api键?
我只是尝试用post检测post中的_api键,但它也不起作用:
map $request_body $api {
"_api" $binary_remote_addr;
default "";
}
limit_req_zone $api zone=api_api:10m rate=30r/m;
limit_req zone=api_api burst=10 nodelay;
答案 0 :(得分:1)
好的,经过数小时的研究和大量的反复试验,我确定了:
$ args 仅包含GET数据
$ request_body 包含POST数据,但仅在使用时才可用:
proxy_pass
fastcgi_pass
uwsgi_pass
scgi_pass
$ request_body 是一个字符串,当可用时未解析为JSON,因此您无法使用$ args执行$ request_body_api。
我无法通过在地图中直接使用$ request_body来实现此功能:
map $request_body $body {
default "";
"~*.*(_api)" $binary_remote_addr;
}
limit_req_zone $body zone=body:10m rate=30r/m;
limit_req zone=body burst=5 nodelay;
我能找到让这个工作的唯一方法就是在包含帖子的标题中添加一个cookie,这样可行,但效率不高,好像帖子请求很大,会消耗很多不必要的资源。
add_header Set-Cookie post_data=$request_body;
map $http_cookie $cook_ {
default "";
"~*post_data=.*(\"_api\")" $binary_remote_addr;
}
limit_req_zone $cook zone=cook:10m rate=30r/m;
limit_req zone=cook burst=5 nodelay;
如果我做了任何不正确的陈述/妄想,或者如果有人知道更好的方法,那么请告诉我,这有效,但有点像黑客!