前后端分离的项目如何防止 api 被第三方利用 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
imherer
V2EX    程序员

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

  •  2
     
  •   imherer 2019-02-14 10:53:19 +08:00 14285 次点击
    这是一个创建于 2436 天前的主题,其中的信息可能已经有所发展或是发生改变。
    假如 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%模拟浏览器引擎,只能加监控,做策略,防止被滥用
    north521
        4
    north521  
       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 就好比做一个文章查看的页面,游客也可以查看所有文章,那么这里如何做鉴权呢?
    dr1q65MfKFKHnJr6
        16
    dr1q65MfKFKHnJr6  
       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  
    PRO
       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
    内网
    rb6221
        45
    rb6221  
       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     Solana     3966 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 35ms UTC 00:16 PVG 08:16 LAX 17:16 JFK 20:16
    Do have faith in what you're doing.
    ubao msn 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