How to implement an external rate limitter?
Closed this issue · 2 comments
I would like to implement a rate limitter, but externally, to be shared between multiple nginx servers.
I already have a service that attends on my POST http://localhost:3000/verify_limits address, which expects a body like below:
{
"uri": "/address/of/this/call",
"orgId" : "xxxxbxa-4a47-4176-b85e-8dbb2f2938a6",
"token": "content of authorization header"
}
uri: The address that the client is calling (r.uri)
orgId: A client certificate attribute extracted from subject. I think I can get this value using r.variables.ssl_client_raw_cert variables, as documented here.
token: The authorization header. I think I can get this value through r.headersIn.Authorization.
As result, it returns the http codes 429, 423 or 200.
Now, I would like to implement an script that when the address "/address/of/this/call" is called, first the njs script needs to call http://localhost:3000/verify_limits and based on it's response (http status code), redirect to another proxy_pass in case of http status code 200 or return 429 or 423.
I've tried to use ngx.fetch on my script, but when using it I always receive and http 500 code from nginx, as if ngx.fetch, even with a very simple code like below:
async function authorize(r) {
let reply = await ngx.fetch("http://localhost:3000/validate_limits", {
method: "POST",
body: { "uri": r.uri, "orgId" : "xxxxbxa-4a47-4176-b85e-8dbb2f2938a6", "token": r.headersIn.Authorization}
});
r.return(200);
}
export default {authorize}
I really appreciate any help.
Thanks
Hi @ranierimazili,
Please make sure that nginx.fetch() receives a body property as a string, using JSON.stringify({{ "uri": r.uri, "orgId" : "xxxxbxa-4a47-4176-b85e-8dbb2f2938a6", "token": r.headersIn.Authorization})
ngx.fetch() converts "body" using ]toString()method, and for objects
toString()` returns the following text "[object Object]".
Thanks for your help...
I've found the reason of my problem... I was using http://localhost:3000 and for some reason nginx was resolving localhost to an ipv6 address... replace to 127.0.0.1 solved the problem and now it's requesting my local service.