Hello all,
We used to use this code below [1] to deal with limit-* case (for example:
ratelimit for sending sms verifycode):
mobile stands for users' mobile phone no. from http post body.
But for other people maybe use `cookie`, `arg` or `mobile_phone` from body
instead.
So how can we avoid hard coding this key in the lua code?
1. lua code like:
location /verifycode {
default_type 'application/json';
#so you can to use set_by_lua from $mobile
set $mobile '';
access_by_lua_block {
local request_method = ngx.var.request_method
local args = nil
if "GET" == request_method then
local arg = ngx.req.get_uri_args()["mobile"] or 0
ngx.var.mobile = arg
elseif "POST" == request_method then
cjson = require "cjson"
local body = ngx.req.get_body_data()
if body then
-- parsing json body for {mobile : 123, address: .... }
local body = cjson.decode(body)
local arg = body.mobile or 0
ngx.var.mobile = arg
end
end
local ratelimit = require "resty.redis.ratelimit"
local lim, err = ratelimit.new("verifycode", "1r/m", 0, 0)
if not lim then
ngx.log(ngx.ERR,
"failed to instantiate a resty.redis.ratelimit
object: ", err)
return ngx.exit(500)
end
local red = { host = "", port = 6379, timeout = 1, pass = "" }
local key = ngx.var.mobile
local delay, err = lim:incoming(key, red)
if not delay then
if err == "rejected" then
return ngx.exit(429)
-- cjson = require "cjson"
-- ngx.say(cjson.encode({ code=1603, message = "Too
Many Requests", successful = true }))
end
ngx.log(ngx.ERR, "failed to limit req: ", err)
return ngx.exit(500)
end
if delay >= 0.001 then
-- the 2nd return value holds the number of excess requests
-- per second for the specified key.
local excess = err
ngx.sleep(delay)
end
}
}
Thanks.