分享一段api限制次数openresty lua脚本

一段仿君子不防小人的脚本,因为还有代理ip这个东西的存在, 无法一次性斩断爬虫
凑合用吧
--by tools.bugscaner.com
--每个ip 每天最多限制请求次数
--为什么使用openresty,是因为这货非常适合做这种事情,速度超乎想象的快
--脚本限制
local cjson = require "cjson" --json处理
local limit_count = require "resty.limit.count"
local returninfo = {status=555,info="limit"}

--获取当前路径
local path = ngx.var.uri

local ifreturn200 = nil

--设置默认限制额度
local limitnb = nil
--设置默认的限制时间  比如一天 或者一个小时
--把你的路径  另辟elseif 吧,limitnb就是每天限制的次数, 自己修改
local allowtime = nil
if path == "/api/whichcdn/" then
	--根据路径来进行分配额度 这个是识别百度爬虫ip
	limitnb = 100
	allowtime = 86400
elseif path == "/api/crackmd5.html" then
	--这个是收录批量查询的限制
	limitnb = 50
	allowtime = 86400
elseif path == "/api/weibo/" then
	limitnb = 300
	allowtime = 86400
elseif path == "/api/zaixianshitu/" then
	limitnb = 100
	allowtime = 86400
elseif path == "/api/baiduyunpassword/" then
	limitnb = 200
	allowtime = 86400
elseif path == "/api/nslookup/" then
	limitnb = 200
	allowtime = 86400
elseif path == "/api/crackmdb/" then
	limitnb = 100
	allowtime = 86400
elseif path == "/api/subdomain/" then
	limitnb = 300
	allowtime = 86400
elseif path == "/api/decompyle/" then
	limitnb = 200
	allowtime = 86400
elseif path == "/api/dezend/" then
	limitnb = 100
	allowtime = 86400
elseif path == "/api/baidusearchtojson" then
	limitnb = 100
	allowtime = 86400
elseif path == "/api/cdn_check.html" then
	limitnb = 100
	allowtime = 86400
elseif path == "/api/altimages.html" then
	limitnb = 200
	allowtime = 86400	
else
	ifreturn200 = true
end

if not ifreturn200 then
	local alltotal = limitnb.."/day"
	--这里是对普通用户的过滤
	local headers=ngx.req.get_headers()
	local ips=headers["X-Forwarded-For"]
        -- 这里的X-Forwarded-For很重要,我采用的cdn加速,只有这个才能获取到真实ip,你是用这个脚本的话,自己测试下了
	local key = string.gsub(ips,"(.*),%s","") or "0.0.0.0"
	--有一个更有意思的省事的办法 就是赋予每个key按照日期相加 这样可以每天12小时候,重新清零
	--非常重要的地方,由于要对每个url都有可能设置限制的需求,对每个url再增加一个标志性后缀
	key = path.."."..key.."."..os.date("%j")
	key = ngx.md5(key)
	local lim, err = limit_count.new("tools_api_limit", limitnb, allowtime)
	delay, err = lim:incoming(key, true)
	if not delay then
		if err == "rejected" then 
			ngx.header["X-RateLimit-Limit"] = alltotal
			ngx.header["X-RateLimit-Remaining"] = 0
			return ngx.say(cjson.encode(returninfo))
		end
	end
	local remaining = err
	ngx.header["X-RateLimit-Limit"] = alltotal
	ngx.header["X-RateLimit-Remaining"] = remaining
else
	return
end

您可能还会对下面的文章感兴趣: