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

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

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

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

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

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

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


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

    我觉得楼主想找的答案,不应该是不能使用“鉴权”,而是无侵入或者低侵入的方案吧。
        27
    Heavytiger   33 天前
    @DavidNineRoc 小程序用的 api,这种有没有教程推荐一下,最近要做,学习一下
        28
    imherer   33 天前
    @index90
    ``我觉得楼主想找的答案,不应该是不能使用“鉴权”,而是无侵入或者低侵入的方案吧``

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

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

    总之,没有绝对的防止手段
        57
    robinlovemaggie   32 天前
    参考微信的完全封闭,路子狂野
        58
    SoulSleep   32 天前
    我不想让第三方利用我的 api,但是又不能做鉴权

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

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

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

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

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

    https://github.com/qwerty472123/wxappUnpacker
        88
    xfriday   31 天前
    1. 不能鉴权
    2. 不让一部分人调用

    这需求要是产品提出来,打死它,狗屁逻辑不通,就跟“我要这个 Button 即是红的,又是蓝的”一样蠢
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3843 人在线   最高记录 4385   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 29ms · UTC 06:37 · PVG 14:37 · LAX 23:37 · JFK 02:37
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1