如何保证API不被别人恶意调用(彩蛋)
这两天比较悠闲,有很多时间可以用来写文章。扯扯淡,哈哈哈今天给大家分享一个纯业务的的东西,也会有代码辅助,但是不多。看名字是不是都觉得很屌哈哈哈哈哈哈哈。
博主是一个标题党。
先给你们上一张小编自己画的图吧。我不知道大家写APi的时候有没有这样的疑惑。。
就是api频繁被恶意调用,有没有这种的,我擦我新写的接口又被爬去了,竟然拼接了参数来不断请求。哎。。。。。
来听小编发生在自己身上的超级恶心的bug
我记得小编在上家公司遇到一个很奇葩的事,我刚写了一个发短信的接口,感觉自己浑身都飘起来了,
感觉功能做出来,各种牛逼,然后呢提测给一个漂亮的小姐姐 诺和下面的这位小姐姐一样漂亮。。
并对我说了一生,大猪蹄子你这个功能没问题可以正常上线。。。
可以上线正式版本,我习以为常的就上线了。
正当我和小姐姐聊天呢,我们Leader拿着个菜刀就过了,小伙子你要逆天啊。。。
我说咋的咋的了,是不是泡你妹子了。我们leader拿着一个账单
你给我哦解释一下,咱们的程序刚上线每一个月,短信费用干了5w多
是不是用户多了,leader说md用户还是那几个我们自己人
然后我看了一下某短信平台嘚消费信息,结果真的发送了这么多验证码。
是不是短信平台出bug了。。。我给老板说得赶紧维权啊
结果给客服小姐姐打电话打了2个小时,最后的结局是我们平台没有bug,一切正常。是你们频繁调用我们接口的。我就怒了,妈的什么破短信平台,垃圾。。。。吞钱啊。。
没办法了,找自身原因吧,我默默打开xsheel 一看日志 我他妈顿时就惊呆了。还在刷验证码
我什么都没有想,就把服务器Tomcat就给关了,结果一个小时损失了几个亿日元。。。。
妈的Leader差点被砍死。。。。。还好我命大。
最后发现了问题所在就是接口没有加认证,被大坏蛋恶意抓取了,然后只要给这个接口传手机,这个接口就开始发短信,我才他们写了一个for循环然后频繁调用我们接口。。。太他妈狠了。。。。。。。
这就是网上流传的短信轰炸机
小编副业写BUG 副业DBUg 哎做一个程序员真累。
今天就给大家分享一个给API接口加认证的方法(只有业务)
我画了一个流程图,先给你们看看~~~~
kingYifan用了20年的画工才花出来的。。。(不喜欢勿喷啊)
来给你们贴代码的时候到了
/***
*spring mvc的请求过滤,权限验证
*KingYiFan
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String path = request.getServletPath();
//走正则表达式 看是否这个接口是否需要认证
if(path.matches(Const.NO_INTERCEPTOR_PATH)){
//不需要直接放行
return true;
}
Map<String,Object> map = new HashMap<String,Object>();
//接受前台的数据 sign是加密的字符串
String sign = request.getParameter("sign");
//前台的时间戳
String timestamp = request.getParameter("timestamp");
//用户的凭证,这个根据业务写
String token =request.getHeader("token");
//判断是否为空 为空直接返回false
if(Tools.notEmpty(sign)&&(Tools.notEmpty(timestamp)&×tamp.length()==13)) {
//验证请求超时
Long _timestamp = Long.parseLong(timestamp);
if (System.currentTimeMillis()/1000 - _timestamp * 1000 > 60 * 1000) {
map = AppUtil.returnResult(map,"fail",Const.PROMPT_TIMEOUT);
logger.info("接口访问失败,请求超时,访问路径:----"+path);
println(response, map);
return false;
}
//验证签名
//String param = path.substring(path.lastIndexOf("/")+1, path.length());
boolean signBool = AppUtil.checkSign(token, sign, timestamp);
if(!signBool){
map = AppUtil.returnResult(map,"fail",Const.PROMPT_WRONGFUL);
logger.info("接口访问失败,验签不正确,访问路径:----"+path);
println(response, map);
return false;
}
}else {
map = AppUtil.returnResult(map,"fail",Const.PROMPT_WRONGFUL);
logger.info("接口访问失败,验签不正确,访问路径:----"+path);
println(response, map);
return false;
}
logger.info("接口访问成功,访问路径:----"+path);
return true;
}
对比的工具类(签名)
/**
* 检测KEY是否正确
* @param paraname 传入参数
* @param FKEY 接收的 KEY
* @return 为空则返回true,不否则返回false
*/
public static boolean checkSign(String paraname, String sign,String timestamp){
paraname = (null == paraname)? "":paraname;
return MD5.md5(paraname+",cnbuilder.cn,"+timestamp).equalsIgnoreCase(sign);
}
上面就是一套验签的服务器端流程,有什么不懂就联系我。
鼓励作者写出更好的技术文档,就请我喝一瓶哇哈哈哈哈哈哈哈。。
微信:
支付宝:
感谢一路支持我的人。。。。。
Love me and hold me
QQ:69673804(16年老号)
EMAIL:69673804@qq.com
友链交换
如果有兴趣和本博客交换友链的话,请按照下面的格式在评论区进行评论,我会尽快添加上你的链接。
网站名称:KingYiFan’S Blog
网站地址:http://blog.cnbuilder.cn
网站描述:年少是你未醒的梦话,风华是燃烬的彼岸花。
网站Logo/头像:http://blog.cnbuilder.cn/upload/2018/7/avatar20180720144536200.jpg