我想了想还是单独贴出来让更多的人看到,大家一起看一下可行性以及是否存在问题。
体验可以到这里 http://blog.eqoe.cn/ 在右边进行搜索

我们可以看到点击搜索的时候客户端发送了 3 次请求。
- 第一次:提交 Get 请求,服务器返回 error=1 表示该关键词没有被内存缓存,需要 Hash 验证
- 第二次:提交 Get 请求,获得一个 TOKEN,然后客户端在此 TOKEN 后增加数字,直到这个字符串 SHA1 值的前4位为0(服务器需要保证 TOKEN 与每个 IP 地址对应)
客户端计算 Hash 示例代码
var tk = "获得的TOKEN内容";
var str = 10000;
var lasthash = "";
while(lasthash.indexOf("0000") != 0){ //如果 lasthash 前4位不是0则持续循环
str++;
lasthash = sha1(tk+str.toString()); //把 Token 和 数字拼接起来
}; //经过多次测试 PC端计算大约需要1-3秒 移动端需要2-5秒
- 第三次:我们将 tk str 以及 要搜索的内容 POST 到服务器上,服务器识别 TOKEN 与 IP 地址相符,并且与 str 合并之后的 sha1 结果前4位为0,服务器返回搜索结果,否则提示客户端进行重试。
如果需要的话你可以对我的 blog 进行压力测试,别打太狠就行。。。
假设使用 C 语言制作客户端计算一个 Hash 需要 2 秒,攻击者使用 16 核电脑和若干代理IP,那么你的服务器每秒只会收到 8 个以下的请求,这种算法应对一般的攻击应该可以无压力的防住吧?