Hi, Lang,
Apache APISIX was designed with this in mind. The `key` supports all nginx
variables, including http_ *, cookie_ *, args_ *, etc.

However, in order to prevent misuse by users, this restriction is not
relaxed at the code level.
Developers need to manually add a key here[1] to unlock this feature.

This is not described in the documentation, welcome to submit PR to improve
the documentation, thank you

[1]
https://github.com/apache/incubator-apisix/blob/master/lua/apisix/plugins/limit-req.lua#L29

Thanks,
Ming Wen, Apache APISIX
Twitter: _WenMing


Lang Wang <[email protected]> 于2020年2月25日周二 下午5:05写道:

> 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.
>

Reply via email to