防止接口被人恶意调用,有哪些可靠地方式? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
panpanpan
V2EX    问与答

防止接口被人恶意调用,有哪些可靠地方式?

  •  1
     
  •   panpanpan 2017-11-10 13:02:28 +0800 7101 次点击
    这是一个创建于 2894 天前的主题,其中的信息可能已经有所发展或是发生改变。
    第 1 条附言    2017-11-10 13:38:16 +08:00
    只是想从技术的角度讨论一下有哪些比较不错的方式。
    1. 接口是对外的
    2. 用户系统是开放注册的
    28 条回复    2017-11-15 16:34:57 +08:00
    mooczz
        1
    mooczz  
       2017-11-10 13:08:17 +08:00 via iPhone
    如果是面向 app 的话,客户端对参数签名,服务端校验
    fashy
        2
    fashy  
       2017-11-10 13:09:41 +08:00
    对内的接口,ip 白名单;对外的接口权限、流量控制
    panpanpan
        3
    panpanpan  
    OP
       2017-11-10 13:13:57 +08:00
    @mooczz 对参数签名的方法感觉同样有可能被破解。
    582033
        4
    582033  
       2017-11-10 13:23:04 +08:00
    oauth2
    springmarker
        5
    springmarker  
       2017-11-10 13:29:11 +08:00
    用户量小且没有用户校验的话,直接 ip ban 掉,简单粗暴
    panpanpan
        6
    panpanpan  
    OP
       2017-11-10 13:30:31 +08:00
    @582033 OAuth2 只是授权,如果谁都能注册呢
    panpanpan
        7
    panpanpan  
    OP
       2017-11-10 13:33:21 +08:00
    @springmarker 想象成一个注册就能用的 APP,黑名单肯定 ban 不完所有代理啊
    cloverstd
        8
    cloverstd  
       2017-11-10 13:41:06 +08:00   1
    @panpanpan #7 你得增加注册成本
    恶意调用不可能完全禁止的
    你得提高别人恶意调用的成本,当『他的调用成本』大于『调用你获取的利益』时,他肯定不会再干了啊
    odirus
        9
    odirus  
       2017-11-10 13:46:59 +08:00
    如果是还没上线,那好办,接口里面一定要通过某种方式传递一些设备信息(例如 IMEI 等)来识别身份;并且要保留验证码机制,根据该设备的请求情况决定是否在关键步骤中开启验证码模式。

    如果是已经上线,但只能取到 IP,那可以根据 IP 维度对用户的请求进行监控,例如连续多次访问敏感接口(发送验证码之类的)则可以考虑对这个 IP 进行降权处理,访问某些接口的时候被 ban 掉。

    ------------------------------------------------------------------------------

    上面可能需要利用到的技术就是复杂验证码、Nginx 动态编程。Nginx 动态编程可以考虑 OpenResty
    honeycomb
        10
    honeycomb  
       2017-11-10 13:47:24 +08:00
    @panpanpan

    如果是 Android 的海外业务,play 渠道的可以考虑 safetyNet Attestation API

    General 的则可以考虑类似反爬虫的策略(简单些的类似 geektest 的 captcha ),毒性越高限制越多。
    app 可以拉 app 包的签名(基本都在用,比如 xx 地图的公开 API)
    honeycomb
        11
    honeycomb  
       2017-11-10 13:48:37 +08:00
    @odirus
    哎,又是一个要 IMEI 的
    xomix
        12
    xomix  
       2017-11-10 13:54:08 +08:00   3
    app 用内部封一个 key+用户密码组合成新的 key 的方法验证,发现内部 key 有恶意访问,就下发新 key 给 app 并且淘汰旧的 key。这样 app 这边就能做到可控。

    注册这块增加注册成本,国内最简单的方案就是绑个手机号。国外没研究过但是绑个 google 市场 id 应该也是不错的选择。

    公司等第三方大规模调用也是一样,两套 key,发现恶意通知对方换 key,发现多次恶意通知对方整改。

    制度上解决比较靠谱,技术上别说自动化,你就是雇佣上几个维护人员 7*24 的根据监控数据调整接口访问,也不一定能解决别人上爬虫。
    odirus
        13
    odirus  
       2017-11-10 13:54:19 +08:00
    @honeycomb

    没什么大惊小怪的,其他方案也有的是

    如果只有存储权限,也可以不用 IMEI 的,只要能确定用户身份即可,之前我们做法是在应用存储区域写一个随机字符串文件,如果存在则在请求的时候发送这个;如果不存在,则生成后再携带发送。

    ----------------------------------------------------------------------------------------------

    不过既然人家都能破解了,,肯定直接替换接口里面的参数,这个时候就可以根据请求请求对 IP 和 deviceID 进行评分,低于某个评分的情况就直接 ban 掉。
    panpanpan
        14
    panpanpan  
    OP
       2017-11-10 14:01:00 +08:00
    @odirus 这种思路跟要求登录然后通过用户信息来识别有些类似,通过大量的日志分析确实可以识别到一些异常用户,可以 ban 掉那些大量请求的,但是从原理上面来说这些信息依然是可以伪造的,所以。。。
    panpanpan
        15
    panpanpan  
    OP
       2017-11-10 14:06:12 +08:00
    @xomix 如何监测 key 有没有被恶意使用我感觉也是问题的关键呢
    gouchaoer
        16
    gouchaoer  
       2017-11-10 14:09:07 +08:00 via Android
    api 限制速率
    odirus
        17
    odirus  
       2017-11-10 14:12:46 +08:00   1
    @panpanpan

    一定要根据自身 APP 的特点哈,我做了一些规则来对设备进行分数评价(这些规则只要不泄露,写爬虫的人肯定不知道),例如:

    1 )调用注册之前一定会调用拉取过首页广告的接口
    2 )一个 IP + deviceId 只会在 60s 内至多调用一次验证码发送接口
    3 )以及更多的特定应用规则

    基本原理就是说系统会根据设备的访问历史记录,对请求进行动态评分,并且在 Nginx 这一层 "恶搞" 分数特别低的一些爬虫,甚至是 ban 掉。

    如果有哪些 IP + deviceId 违反了上面的规则,我就会对这台设备进行扣分,当分数低于某个阈值的时候,会通过 OpenResty 直接返回相应的错误,而不是转发到后端程序。
    gouchaoer
        18
    gouchaoer  
       2017-11-10 14:13:14 +08:00 via Android
    panpanpan
        19
    panpanpan  
    OP
       2017-11-10 14:25:18 +08:00
    @gouchaoer @odirus Got it.
    用户量大了之后这确实是一些很不错的防爬虫手段。但是我最初提问的初衷其实是如何防止别人拦截请求,然后来模拟请求。哈哈
    crab
        20
    crab  
       2017-11-10 14:45:25 +08:00
    @panpanpan 上谷歌验证码
    picone
        21
    picone  
       2017-11-10 14:50:27 +08:00
    App 或者网页都可以做一些用户行为手机分析,很多软件都干这事。
    比如我要注册,那肯定要点击输入框,然后 balabalabala 账号,balabala 密码,然后点击注册,这里屏幕触摸很多,网页的话还能进行捕捉键盘,所有用户输入都能捕捉到,然后收集压缩加密发给服务器进行分析,就知道是真人还是假的人了。理论上还是可以破解,但是破解成本挺大的
    sculley
        22
    sculley  
       2017-11-10 17:57:17 +08:00
    HTTPS ?
    panpanpan
        23
    panpanpan  
    OP
       2017-11-10 18:01:48 +08:00
    @sculley HTTPS 只能防止传输过程中有人劫持修改,不能防止模拟请求
    honeycomb
        24
    honeycomb  
       2017-11-10 19:55:29 +08:00
    @odirus

    “在应用存储区域写一个随机字符串文件,如果存在则在请求的时候发送这个;如果不存在,则生成后再携带发送。 ”
    这样用 UUID/InstanceID 的做法比较能接受,但是如果要获取设备持久不可更改的识别码,一般来说,除去少量服务外是不能接受的。应用只能在一次安装到卸载为止的生命周期中识别特定设备。


    “如果有哪些 IP + deviceId 违反了上面的规则,我就会对这台设备进行扣分”
    挺好的做法
    flynaj
        25
    flynaj  
       2017-11-10 20:05:08 +08:00 via Android
    跟百度的 API 一样免费的有次数限制
    leopku
        26
    leopku  
       2017-11-10 20:49:54 +08:00
    HMAC 算法
    wellCh4n
        27
    wellCh4n  
       2017-11-11 15:24:46 +08:00
    阿里的 API 网关好像是后端加密之后放进 header 里面做一个转发。
    xomix
        28
    xomix  
       2017-11-15 16:34:57 +08:00
    @panpanpan 根据 key 和用户写日志啊,突发服务器资源吃紧的时候日志一目了然
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5970 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 06:19 PVG 14:19 LAX 23:19 JFK 02:19
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86