简单的安全防范 web时代的今天,我们经常会暴露一些接口给外网,但是很多作为前端工程师,也是需要在互联网的今天做一点攻防。不能直接让人直接访问你的接口,所以,本篇文章主要简单的介绍下。如何的简单的实现防刷。
文章主要采用node.js作为介绍。
首先,我们理解下,一个接口没有任何防刷。你只需要打开浏览器,直接找到对应的接口,直接刷新就可以直接搞定接口。这样我们的风险还是很高的。让刷的难度稍微高一点。
最简单的做法就是,Token验证和访问限制。
1.我们需要server端生成一段随机数。1 2 3 4 injectAccessToken(req, res, next) { req._access_token = Math.random().toString(26).slice(2); next(); }
2.把Token注入到页面中1 2 3 4 5 6 7 8 9 webInject:function(html,token,callback){ var htmlEndIndex = html.indexOf('</html>'); var tokenScript = '<script>window.' + this.config.webTokenVarName + '=' + token + '</script>'; var prevHtml = html.substring(0, htmlEndIndex); var nextHtml = html.substr(htmlEndIndex); prevHtml += tokenScript; prevHtml += nextHtml; callback(null, prevHtml); }
3.页面请求把Token带回来
页面请求带着自定义的Token回传,注意,这个地方可以自己实现一些算法和混淆的东西。我这里提供一个东西。就是通过字符串拆分,把生成的Token放在html中,获取的时候也是随机的。达到每次获取都不一样。 记住标签随机,id值随机生成,在server端输出给html。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 <samp id="_CWXF0" style="display:none;" >f</samp> <i id="_CWXF1" style="display:none;" >k</i> <sub id="_CWXF2" style="display:none;" >2</sub> <tt id="_CWXF3" style="display:none;" >d</tt> <bdo id="_CWXF4" style="display:none;" >f</bdo> <b id="_CWXF5" style="display:none;" >d</b> <cite id="_CWXF6" style="display:none;" >7</cite> <tt id="_CWXF7" style="display:none;" >b</tt> <code id="_CWXF8" style="display:none;" >e</code> <dfn id="_CWXF9" style="display:none;" >g</dfn> <time id="_CWXF10" style="display:none;" >3</time> <code id="_CWXF11" style="display:none;" >8</code> <sub id="_CWXF12" style="display:none;" >1</sub> <code id="_CWXF13" style="display:none;" >a</code> <em id="_CWXF14" style="display:none;" >o</em> <bdo id="_CWXF15" style="display:none;" >b</bdo> <i id="_CWXF16" style="display:none;" >d</i> <i id="_CWXF17" style="display:none;" >e</i> <sup id="_CWXF18" style="display:none;" >j</sup> <small id="_CWXF19" style="display:none;" >9</small> <code id="_CWXF20" style="display:none;" >m</code> <em id="_CWXF21" style="display:none;" >4</em> <small id="_CWXF22" style="display:none;" >9</small> <cite id="_CWXF23" style="display:none;" >c</cite> <abbr id="_CWXF24" style="display:none;" >g</abbr> <tt id="_CWXF25" style="display:none;" >5</tt> <code id="_CWXF26" style="display:none;" >h</code> <sup id="_CWXF27" style="display:none;" >6</sup> <sub id="_CWXF28" style="display:none;" >5</sub> <span id="_CWXF29" style="display:none;" >f</span> <sup id="_CWXF30" style="display:none;" >0</sup> <i id="_CWXF31" style="display:none;" >3</i> <label id="_CWXF32" style="display:none;" >7</label> <span id="_CWXF33" style="display:none;" >e</span> <code id="_CWXF34" style="display:none;" >9</code> <label id="_CWXF35" style="display:none;" >6</label> <bdo id="_CWXF36" style="display:none;" >3</bdo> <code id="_CWXF37" style="display:none;" >b</code> <cite id="_CWXF38" style="display:none;" >3</cite> <acronym id="_CWXF39" style="display:none;" >3</acronym> <sub id="_CWXF40" style="display:none;" >m</sub> <dfn id="_CWXF41" style="display:none;" >8</dfn> <map id="_CWXF42" style="display:none;" >o</map> <strong id="_CWXF43" style="display:none;" >9</strong> <sup id="_CWXF44" style="display:none;" >j</sup> <em id="_CWXF45" style="display:none;" >d</em> <script> (function (w){ var r = "" ; function g(id){ return document.getElementById(id).innerHTML; } r += g("_CWXF0" );r += g("_CWXF1" );r += g("_CWXF2" );r += g("_CWXF3" ); r += g("_CWXF4" );r += g("_CWXF5" );r += g("_CWXF6" );r += g("_CWXF7" ); r += g("_CWXF8" );r += g("_CWXF9" );r += g("_CWXF10" );r += g("_CWXF11" ); r += g("_CWXF12" );r += g("_CWXF13" );r += g("_CWXF14" );r += g("_CWXF15" ); r += g("_CWXF16" );r += g("_CWXF17" );r += g("_CWXF18" );r += g("_CWXF19" ); r += g("_CWXF20" );r += g("_CWXF21" );r += g("_CWXF22" );r += g("_CWXF23" ); r += g("_CWXF24" );r += g("_CWXF25" );r += g("_CWXF26" );r += g("_CWXF27" ); r += g("_CWXF28" );r += g("_CWXF29" );r += g("_CWXF30" );r += g("_CWXF31" ); r += g("_CWXF32" );r += g("_CWXF33" );r += g("_CWXF34" );r += g("_CWXF35" ); r += g("_CWXF36" );r += g("_CWXF37" );r += g("_CWXF38" );r += g("_CWXF39" ); r += g("_CWXF40" );r += g("_CWXF41" );r += g("_CWXF42" );r += g("_CWXF43" ); r += g("_CWXF44" );r += g("_CWXF45" ); w.tokenName=r; })(window) </script>
4.校验token是否合法
在路由的地方加入拦截器,达到获取Token的目的,这里为了统一处理前端,建议放在header中,传递,你可以在前端统一封装的ajax处统一处理,以达到不影响业务代码的目的。1 2 3 4 5 6 7 8 9 10 11 verifyToken(req, res, next) { if (req.headers['token_fe' ]) { next(); } else { res.jsonp({ code: -1, ret: false , msg: 'access not vaildate' }); } }
这样就实现了最简单的Token防刷,当然重要的是,你可以把token放在内存中,内存中加入过期时间,和有效的规则,比如,一分钟这个Token请求多少次。就不能再次请求等。可以可以注入IP,以IP的模式来校验不能多次请求。