V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
imherer
V2EX  ›  程序员

前后端分离的项目如何防止 api 被第三方利用

  •  2
     
  •   imherer · 2019-02-14 10:53:19 +08:00 · 13691 次点击
    这是一个创建于 2109 天前的主题,其中的信息可能已经有所发展或是发生改变。
    假如 api 是不需要任何鉴权,就像 v 站的 api 一样,第三方可以利用 api 去做一些小程序或者内容展示的网站

    我不想让第三方利用我的 api,但是又不能做鉴权

    这个好像是不能杜绝的吧,只能从利用 api 的难度方面入手?
    88 条回复    2019-02-15 19:44:31 +08:00
    ttvast
        1
    ttvast  
       2019-02-14 10:55:08 +08:00
    Referer 控制
    c0878
        2
    c0878  
       2019-02-14 10:56:53 +08:00
    IP 白名单
    liuxey
        3
    liuxey  
       2019-02-14 10:57:55 +08:00   ❤️ 3
    既然没有鉴权,完全杜绝不可能,通过编码能 100%模拟浏览器引擎,只能加监控,做策略,防止被滥用
    li24361
        4
    li24361  
       2019-02-14 11:00:03 +08:00
    为什么不能鉴权?
    确实需要开放,那就限定 ip 调用次数,能防小白
    Inside
        5
    Inside  
       2019-02-14 11:00:45 +08:00
    你想一下,为什么你能区别自己的前端和第三方前端,如果你能从逻辑上区别,那说明可以做鉴权嘛。
    imherer
        6
    imherer  
    OP
       2019-02-14 11:01:14 +08:00
    @c0878 这些 API 都是客户从浏览器发起请求的,IP 白名单不行吧
    imherer
        7
    imherer  
    OP
       2019-02-14 11:01:59 +08:00
    @ttvast 这个好像也能模拟吧
    fishioon
        8
    fishioon  
       2019-02-14 11:02:17 +08:00 via iPad   ❤️ 2
    不鉴权肯定没办法杜绝,不过可以增加一些利用的难度;
    比如 api 调用中增加一个 key 参数,这个 key 有效期为一天(或者更短)
    这个 key 如何传递到客户端呢?比如在页面中返回,同时页面中对该 key 进行算法加密等等(就是让别人没那么容易拿到这个 key )
    no1xsyzy
        9
    no1xsyzy  
       2019-02-14 11:02:19 +08:00   ❤️ 1
    最后就是个互相赛跑的游戏
    shuax
        10
    shuax  
       2019-02-14 11:03:01 +08:00
    和防爬虫一样
    imherer
        11
    imherer  
    OP
       2019-02-14 11:03:27 +08:00
    @Inside 好像区分不了。因为所有的请求都是在客户端发起的,只要是在客户端,第三方都可以模拟。 应该只能像 3 楼说的
    whypool
        12
    whypool  
       2019-02-14 11:03:49 +08:00   ❤️ 2
    限制请求的并发,主要防爬虫一波流

    ip 请求频率限制,超过黑名单
    NjcyNzMzNDQ3
        13
    NjcyNzMzNDQ3  
       2019-02-14 11:04:01 +08:00
    淘宝的 security-x5 了解下,分分钟想让你砸了电脑 :doge
    Malthael
        14
    Malthael  
       2019-02-14 11:04:08 +08:00
    @imherer ip 白名单是你部署前端服务器的 ip,跟客户浏览器在哪打开的网站没有关系。
    imherer
        15
    imherer  
    OP
       2019-02-14 11:04:50 +08:00
    @li24361 就好比做一个文章查看的页面,游客也可以查看所有文章,那么这里如何做鉴权呢?
    cedoo22
        16
    cedoo22  
       2019-02-14 11:07:05 +08:00
    ... 第三方可以利用 api 去做一些小程序或者内容展示的网站

    我不想让第三方利用我的 api,但是又不能做鉴权 ....


    你这需求怕是要打锤哦, 你到底要不要第三方用你的 API ????
    想一顿爆锤
    好了,拖下去
    imherer
        17
    imherer  
    OP
       2019-02-14 11:09:13 +08:00
    @cedoo22 也许是没表达清楚,我的意思是第三方可能会利用 api 去做小程序或者展示网站,但是我不想让他们这样去做...
    DavidNineRoc
        18
    DavidNineRoc  
       2019-02-14 11:13:41 +08:00   ❤️ 1
    如果实在 web, 基本不太可能.
    小程序的话,别人看不到你的源码.
    每一次请求都声称一个 sign 参数验证.
    前端: 加点时间戳, 自己小程序写死一个 code, 然后手写一个前后端通用的对称加密算法就行了.
    后端: 解密之后,验证是否过期等等...
    cando
        19
    cando  
       2019-02-14 11:15:38 +08:00   ❤️ 1
    参数加密后台验证,用户认证 auth 等等。
    或者直接不提供接口咯
    mauve
        20
    mauve  
       2019-02-14 11:17:38 +08:00   ❤️ 1
    nginx gateway
    flyingghost
        21
    flyingghost  
       2019-02-14 11:19:11 +08:00   ❤️ 1
    鉴权 = 识别客户端合法性。你都放弃鉴权了,等于是放弃识别能力了,又怎么要求“识别”自己人和第三方呢?
    就像我家大门不需要钥匙推门就进。但我要防贼。这么等价替换的话,你就会发现,你得有一双贼眼,能发现贼身上自带的一些本征:衣着、神情、习惯动作、气味、面相、指纹、DNA。。。
    然鹅,以上在 http 世界都可以仿冒,仿冒门槛还挺低,成本和技巧难度远低于 Neal Caffrey 仿冒一个良民。
    q397064399
        22
    q397064399  
       2019-02-14 11:20:06 +08:00
    @imherer #17 这本身在逻辑上就是矛盾的.. 既不想给门上锁,又不想小偷轻易偷到你的东西
    YzSama
        23
    YzSama  
       2019-02-14 11:21:16 +08:00 via iPhone
    内网
    geelaw
        24
    geelaw  
       2019-02-14 11:23:58 +08:00 via iPhone
    @flyingghost #21 鉴权是识别用户是否有访问资源权利的过程,和客户用什么渠道去访问没关系。
    fakeshadow
        25
    fakeshadow  
       2019-02-14 11:24:38 +08:00
    把游客的 rate limit 做低点就凑合吧。
    index90
        26
    index90  
       2019-02-14 11:31:38 +08:00
    不想让第三方利用,首先你需要一个能够鉴别什么请求是第三方的规则。
    方法有很多种,AK+SK,JWT,等等,如果这些都称作鉴权,那意思就是不能使用规则。
    不能使用规则的话,就划一个 private network,把第三方隔离出去。

    我觉得楼主想找的答案,不应该是不能使用“鉴权”,而是无侵入或者低侵入的方案吧。
    Heavytiger
        27
    Heavytiger  
       2019-02-14 11:35:09 +08:00
    @DavidNineRoc 小程序用的 api,这种有没有教程推荐一下,最近要做,学习一下
    imherer
        28
    imherer  
    OP
       2019-02-14 11:35:23 +08:00
    @index90
    ``我觉得楼主想找的答案,不应该是不能使用“鉴权”,而是无侵入或者低侵入的方案吧``

    就是这个意思,我表达的不对
    DavidNineRoc
        29
    DavidNineRoc  
       2019-02-14 12:00:49 +08:00
    @Heavytiger 直接搜 sign 参数验证. 很多 api 后端与后端的都是使用这种方式. 如短信平台之类的,如果是小程序,你的源代码别人看不见,可以当做`后端`代码
    如果是 web, 代码能被别人看到,那么内网通信 api 是最好的做法
    ttvast
        30
    ttvast  
       2019-02-14 12:08:15 +08:00
    @imherer 爬虫你是很难防的,就算是鉴权也不能。
    但是根据你的描述,主要是防止其他网站调用你的 API,这样就可以通过 referer 来禁用
    flyingghost
        31
    flyingghost  
       2019-02-14 12:08:24 +08:00
    @geelaw #24 我的意思是对比现实世界,除了协议信息“钥匙”之外会有大量协议之外的本征信息逸散出来供我们利用。但在计算机世界 http 调接口这个场景下,ip、referer、ua、时频、参数特征和分布。。。本征信息少很多,而且要么无法利用,要么伪造简单,要么效果不佳。

    其实 lz 提出的问题 X 背后,我更好奇的是问题 Y:为什么会有这样的需求场景?原始需求有没有放弃鉴权之外的其他方案?
    chinvo
        32
    chinvo  
       2019-02-14 12:11:36 +08:00 via iPhone
    客户端合法性是个无解的问题,只能不断玩躲猫猫的游戏,没法从根本上杜绝
    xpresslink
        33
    xpresslink  
       2019-02-14 12:19:08 +08:00
    如果不鉴权的话,楼主你从逻辑上如何区别客户端和第三方?行为上有什么不同?
    neko2
        34
    neko2  
       2019-02-14 12:19:32 +08:00
    这和爬虫和反爬虫其实是一个道理。只能增加反爬难度
    Junn
        35
    Junn  
       2019-02-14 12:22:52 +08:00 via iPhone
    加密啊
    deepdark
        36
    deepdark  
       2019-02-14 12:30:05 +08:00 via Android
    不做鉴权的话就前端生成用户指纹,然后把用户行为记录下来同步给风控端,风控端通过分析用户行为给到后端该用户是人是鬼,行为是否合法等,后端再考虑接口要不要返回数据。但是这一整套风控端搞下来,需要用户行为模型,还有一些规则。而且要保证是实时分析和处理。不是一件容易的事
    mooncakejs
        37
    mooncakejs  
       2019-02-14 12:57:07 +08:00 via iPhone
    没办法的啊。只能提高难度让它没有收益。
    yuangezhizaobak
        38
    yuangezhizaobak  
       2019-02-14 13:03:50 +08:00
    @NjcyNzMzNDQ3 security-x5 是什么?
    zjsxwc
        39
    zjsxwc  
       2019-02-14 13:07:10 +08:00 via Android
    最简单方式就是定期改接口
    Chingim
        40
    Chingim  
       2019-02-14 13:13:00 +08:00 via Android
    @deepdark 用户行为的数据不是也可以伪造吗?
    deepdark
        41
    deepdark  
       2019-02-14 13:27:37 +08:00 via Android
    @Chingim 可以,但是伪造出来的数据不够顺滑,比如鼠标移动范围,速度,页面停留时间等等。况且伪造这个,对于爬虫来说爬取效率就降低了,对于规则的研究成本高了。说白了爬虫和防爬就是回合制,不断的完善自己的过程
    xuanbg
        42
    xuanbg  
       2019-02-14 13:35:23 +08:00
    生成一个证书,给用户发个公钥,调用 API 需要提供公钥加密的密码
    wizardoz
        43
    wizardoz  
       2019-02-14 13:38:06 +08:00   ❤️ 1
    把前端项目改为后端渲染模式。API 服务对外不可见,只有服务端的前端服务自己可访问。用户拿到的就是渲染后的数据,同时也实现了前后端分离
    580a388da131
        44
    580a388da131  
       2019-02-14 13:43:57 +08:00 via iPhone
    内网
    janus77
        45
    janus77  
       2019-02-14 13:52:10 +08:00 via iPhone
    这么折腾还是直接加个鉴权来的舒服,毛病。
    dapang1221
        46
    dapang1221  
       2019-02-14 13:52:32 +08:00
    你的客户端是什么端,ios 安卓这种应该可以加客户端证书,双向验证,H5 网页的话,这个真没办法,前端再怎么加密基本也能被破
    hilbertz
        47
    hilbertz  
       2019-02-14 13:56:20 +08:00
    限流啊
    azhangbing
        48
    azhangbing  
       2019-02-14 14:27:51 +08:00 via iPhone
    楼主又不加锁还想防盗 怎么可能
    Trumeet
        49
    Trumeet  
       2019-02-14 14:29:53 +08:00
    如果不是什么要紧的东西,开放个 API 也挺好的。
    feikeq
        50
    feikeq  
       2019-02-14 15:11:30 +08:00
    如果是网站,你可以在后端判断一下来访的地址是否合法;
    如果是客户端,那你就要协定一种密钥方式,提交数据时后端难证`密钥是否合法;
    JesseHeisenberg
        51
    JesseHeisenberg  
       2019-02-14 16:16:02 +08:00
    这应该叫防重放吧。。。。后台动态参数,前端非对称加密后放到 header。只有你能用。。。。
    keepsmilence
        52
    keepsmilence  
       2019-02-14 16:17:08 +08:00
    @flyingghost 这个比喻好,不想鉴权的需求就好比不要上锁还想要防小偷似的;
    lcy630409
        53
    lcy630409  
       2019-02-14 16:23:21 +08:00
    加一个 key 吧,就明文给前台,但是这个 key 不规律的自动更换,能挡住大部分人了
    pynix
        54
    pynix  
       2019-02-14 16:26:51 +08:00
    rate limit
    encro
        55
    encro  
       2019-02-14 16:33:57 +08:00
    首先,你怎么得到这个客户端是自己的?
    假如客户端是浏览器,服务端下发一个 session token 给客户端浏览器,客户端浏览器通过这个 session token 取得会话权。(既然是 session 就要有时间限制)
    假如客户端是手机,需要 @xuanbg 说的: 生成一个证书,给用户发个公钥,调用 API 需要提供公钥加密的密码
    kisshere
        56
    kisshere  
       2019-02-14 16:41:19 +08:00
    个人一点意见,什么价 referer 简直就是笑话,限制 ip 次数你拿各种代理池闹着玩的,是我的话,前端和后端通信密文传输,密文的加密结果涉及到各种用户的鼠标手势、停留时间等等,当然这个也不可能完全防得住

    总之,没有绝对的防止手段
    robinlovemaggie
        57
    robinlovemaggie  
       2019-02-14 16:47:35 +08:00
    参考微信的完全封闭,路子狂野
    SoulSleep
        58
    SoulSleep  
       2019-02-14 16:48:51 +08:00
    我不想让第三方利用我的 api,但是又不能做鉴权

    为啥不行,JWT、oauth2 都可以
    xnode
        59
    xnode  
       2019-02-14 16:50:10 +08:00
    放在内网里
    lhstock
        60
    lhstock  
       2019-02-14 16:51:17 +08:00
    求教一下 怎么获取别人的 API。
    t2doo
        61
    t2doo  
       2019-02-14 17:28:00 +08:00
    重要字段插入时加个密,取出显示时解个密,这样搞可操作嘛?
    lpreterite
        62
    lpreterite  
       2019-02-14 17:58:02 +08:00
    APP 用的话肯定能加鉴权啊,jwt 和 oauth2 肯定能帮到你。
    hheedat
        63
    hheedat  
       2019-02-14 18:04:42 +08:00
    这和前后端分离没关系,只是接口比页面用起来方便
    justfly
        64
    justfly  
       2019-02-14 18:13:23 +08:00
    防爬虫的策略都可以用,想要更加高效的不可能,这本质就是个防爬虫问题。
    coolcoffee
        65
    coolcoffee  
       2019-02-14 18:30:15 +08:00
    写爬虫不怕限制游客的单 IP 次数,大不了就花钱买动态 ip 可以绕过。

    但是强制要求登录之后有频率限制, 频率过快以及注册都有 Google Recaptcha 就歇菜了。
    index90
        66
    index90  
       2019-02-14 18:37:57 +08:00
    要完全无侵入的话,上 ServiceMesh,由 SideCar 挟持流量并负责接口的鉴权问题
    opengps
        67
    opengps  
       2019-02-14 18:53:39 +08:00
    首先一楼说的 reffer 足够过滤很多了,其次可以定期该返回规则,这样第三方总有一点会失去耐性不再跟着改代码
    yankebupt
        68
    yankebupt  
       2019-02-14 22:11:04 +08:00
    @imherer 随便想到的一个
    未授权第三方最怕的是什么?是版本更新.....抓到的 API 全部重改....

    最简单就一次做 255 个前后端微改动配套版本,js+后端每天换一个...
    小程序要想全部抓全概率远低于 1/255....

    当然我觉得还是不要把事情做绝好了...只要对你流量影响不大,可以抓抓第三方的调用记录看看他们到底想干什么的...
    Narcissu5
        69
    Narcissu5  
       2019-02-14 23:44:59 +08:00
    我感觉 webdriver 还没什么搞不下来的网站。

    单纯保护 API 的话前端混淆一下也就差不多了,js 的脚本语言特性肯定可以被逆向的,但是成本还是比较高的。而且一旦 API 又改动就思密达,这其实就是种赛跑
    KomeijiSatori
        70
    KomeijiSatori  
       2019-02-15 00:01:42 +08:00
    @DavidNineRoc 其实小程序可以 dump 源码的(
    johnnie502
        71
    johnnie502  
       2019-02-15 02:27:18 +08:00
    楼主在 6 楼说是从浏览器过来的,后面又说客户端,到底是浏览器还是客户端。浏览器的话就很简单了,CORS,referral
    DavidNineRoc
        72
    DavidNineRoc  
       2019-02-15 09:34:48 +08:00
    @KomeijiSatori 具体如何做,应该不太可能?
    imherer
        73
    imherer  
    OP
       2019-02-15 09:39:52 +08:00
    @yankebupt 这种定期更换 API 的方法,如何做成自动的呢?
    最好是在不重新发布版本的前提下完成? 有什么思路吗?
    stephenliubp
        74
    stephenliubp  
       2019-02-15 09:47:26 +08:00
    BFF 中间层,用 Node 或者 PHP 写一层,渲染出页面,用户看到后看似传统的前后端未分离的效果一样。
    ugu
        75
    ugu  
       2019-02-15 09:51:30 +08:00
    @ttvast 这个不行哦
    ralaro
        76
    ralaro  
       2019-02-15 10:01:03 +08:00
    @DavidNineRoc 小程序也可以反编译拿到源代码的
    locoz
        77
    locoz  
       2019-02-15 11:21:28 +08:00 via Android
    这个问题本质上来讲其实就是一个反爬虫问题,从一个爬虫工程师的角度来看,这个问题是无解的。你只能做到尽可能地提高第三方调用你 api 的难度,但不可能完全防止住,因为再强的反爬也会被破解掉,无非就是成本问题而已。
    提升调用难度之后如果第三方调用了你的 api 后所得到的收益低于调用的成本,那基本就会放弃去搞了,这是最直接的办法。
    shapl
        78
    shapl  
       2019-02-15 11:36:03 +08:00
    防火墙,请求次数 1 分钟达到 30 次之类的,拉黑 60 分钟。
    unco020511
        79
    unco020511  
       2019-02-15 12:27:19 +08:00
    请问你是 12306 的研发吗
    yankebupt
        80
    yankebupt  
       2019-02-15 13:41:13 +08:00
    @imherer 其实我觉得都没必要那么过分...写个脚本改改调用名称,参数顺序甚至改改调用名后缀就够了...
    根据用户浏览器指纹 /ip 段随机指定一个版本给他,最大限度保证每个普通用户“历史记录”页面完整性,如果发现滥用就把所有这个指纹的访问切到高危访问去,一小时或一个 session 换几次版本,浏览器没历史记录可查也活该就是了...
    yankebupt
        81
    yankebupt  
       2019-02-15 13:48:18 +08:00
    觉得楼主不想搞鉴权已经不容易了,本来鉴权挺好的也不费多少资源,被大毒瘤们一鉴权就扯实名扯隐私收集扯这个那个搞臭掉了......
    不知楼主的站有没有一般屌丝用的版本(不搞鉴权的话猜测很可能有个一般不登陆展示用的页面),哪天没事可以去看看^_^
    niknik
        82
    niknik  
       2019-02-15 13:51:32 +08:00
    前后端令牌对比,令牌生成再加密
    Amecy
        83
    Amecy  
       2019-02-15 15:00:02 +08:00
    ssr + jwt 呢?
    tonyaiken
        84
    tonyaiken  
       2019-02-15 15:23:50 +08:00
    @Malthael 楼主讨论的情况就是请求是从浏览器发出的,这种情况没法做 IP 白名单。
    DavidNineRoc
        85
    DavidNineRoc  
       2019-02-15 16:03:43 +08:00
    @ralaro 源码是放在腾讯上面的,你怎么反编译?
    zqx
        86
    zqx  
       2019-02-15 16:37:25 +08:00
    前后端分离不变,中间加 node 服务器。前端请求 node 服务器,node 服务根据 referer 过滤第三方的请求,后端 API 只供 node 服务内部调用,不对外暴露
    KomeijiSatori
        87
    KomeijiSatori  
       2019-02-15 16:50:27 +08:00   ❤️ 1
    @DavidNineRoc 小程序运行会缓存到本地的, 并且可以解开混淆

    https://github.com/qwerty472123/wxappUnpacker
    xfriday
        88
    xfriday  
       2019-02-15 19:44:31 +08:00
    1. 不能鉴权
    2. 不让一部分人调用

    这需求要是产品提出来,打死它,狗屁逻辑不通,就跟“我要这个 Button 即是红的,又是蓝的”一样蠢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2673 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 43ms · UTC 05:17 · PVG 13:17 · LAX 21:17 · JFK 00:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.