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

get 请求到的数据如何能不被别人扒下来

  •  
  •   Lpl ·
    penglongli · 2016-10-18 23:45:29 +08:00 · 5744 次点击
    这是一个创建于 2740 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如有个 GET 类型的 api :https://www.xxx.com/api/article/list

    我们可以通过工具查看到 api 返回的值,那么等于说这个接口是暴露出来了(或者 app 中反编下源码也能找到对应的 api )。那么不就是可以通过程序调用 api 把这些数据拖出来了么?

    现在很多 WEB 端网站用的都是 view 层模板的形式, GET 请求得到的直接是页面,这种自然不会把数据给暴露出来。 但是对于有很多 RESTful 接口的网站,数据都会被暴露出来,然后就能把暴露出来的数据扒下来。如果不想把这些数据扒下来的话要怎么办?

    我想了两个办法:

    1. 类微信那种的,加 token ;
    2. 增加 IP 限制,无论是在代码或者 Nginx 做配置都行,限定特定 IP 访问。

    不知道有没有其它解决办法? 还有第一个,如果用加 token 解决的话要怎么弄。。

    31 条回复    2016-10-19 23:53:56 +08:00
    ooTwToo
        1
    ooTwToo  
       2016-10-18 23:55:07 +08:00   ❤️ 2
    客户端:
    - 往 header 里面增加一个 sign ,算法可以是: MD5(secretkey+ timestamp)。
    - 往 header 里面增加一个 timestamp 。

    服务端:

    - 验证 timestamp 有效性(一般早于服务器时间 10 分钟左右)
    - 验证 sign 有效性( MD5(secretkey+ timestamp))


    以上,个人经验。
    Lpl
        2
    Lpl  
    OP
       2016-10-18 23:57:45 +08:00 via Android
    @ooTwToo 这个不错哎,可以试试,感觉也很优雅
    ooTwToo
        3
    ooTwToo  
       2016-10-19 00:02:10 +08:00 via iPhone
    @Lpl QAQ 优雅算不上,只是每个请求都要这样重复很蛋疼…
    hshpy
        4
    hshpy  
       2016-10-19 00:51:41 +08:00 via iPhone
    只能增加爬虫获取数据的难度,具体看反爬虫,找一两种实现吧
    msg7086
        5
    msg7086  
       2016-10-19 01:00:10 +08:00
    其实并没有办法。任何你程序能读到的信息,全世界人都能读到。

    只是简单点还是难点的问题。
    ibigbug
        6
    ibigbug  
       2016-10-19 01:07:33 +08:00
    > GET 请求得到的直接是页面,这种自然不会把数据给暴露出来

    一样是暴露的,可以通过解析页面数据获取想要的数据。
    txlty
        7
    txlty  
       2016-10-19 01:12:00 +08:00
    被人盯上,且对方肯花时间和经济成本。那就基本上不可防了。
    txlty
        8
    txlty  
       2016-10-19 01:26:57 +08:00
    其实可以耍点损招让对方难受一下。比如,识别出某个请求明显来自爬虫,然后可以在正常数据中,循环穿插大量重复数据、错误数据、随机数据、垃圾数据。
    这是最好的方式。比直接封掉对方 IP 更有效。
    bwangel
        9
    bwangel  
       2016-10-19 08:13:43 +08:00
    @ooTwToo ,请问一下客户端这个 `secretkey` 得要服务器事先发送过来吧?
    mcfog
        10
    mcfog  
       2016-10-19 08:21:07 +08:00 via Android
    a.通过工具看请求或者拆你的客户端和你是 get 还是 post 无关,一样是都能拆出来
    b.get 一个页面数据一样在页面里,一样暴露出来,不如说你要展示给用户当然就一定暴露出来
    c.先把业务做好再来考虑防抓,内容真的好的话会有大学生兼职人工抄你的内容根本挡不住,靠防抓是做不成业务的
    finian
        11
    finian  
       2016-10-19 08:39:13 +08:00   ❤️ 2
    防不了,最多也只能增加破解成本。像一楼的方案,拿到 `secretkey ` 就可以破解了。一般通过以下方案增加破解成本:
    - 使用 HTTPS
    - 使用 SSL Pinning
    - 客户端数据加密方案(一定程度上保护 secretkey 等敏感数据)
    - 客户端加固方案(加壳、插花、防内存 dump 、防篡改、防调试。。。)
    annielong
        12
    annielong  
       2016-10-19 09:02:25 +08:00
    手机淘宝天猫好像直接走 443 端口了,嗅探不到,微信一些第三方公众号有时候能嗅探到 api ,但是看不到网页的图片 j 、 js 、 css 资源
    ooTwToo
        13
    ooTwToo  
       2016-10-19 09:04:24 +08:00 via iPhone
    @bwangel 是的,客户端和服务器约定好的。
    qianddream
        14
    qianddream  
       2016-10-19 09:25:05 +08:00
    view 层模板和 RESTful 都会将数据公开在网上,是一样的。

    想要防爬虫的话,只能从如何判别正常用户和爬虫入手,就算你判别出来了还有模拟浏览器的方法可以抓。

    微信和淘宝都是可以抓取数据的,不过代价很高。

    如果是敏感信息不显示只做验证用的话,建议 hash ,再加过期验证。
    killerv
        15
    killerv  
       2016-10-19 09:52:18 +08:00
    完全防御是不可能的,最多增加抓取成本。
    misaka19000
        16
    misaka19000  
       2016-10-19 09:57:25 +08:00
    楼主的思路应该转变一下,是这样:
    不要想完全防御爬虫,只需要让爬虫的制作者进行爬取的成本高于他所获得的收益即可
    alouha
        17
    alouha  
       2016-10-19 10:20:26 +08:00
    @ooTwToo timestamp 这个是客户端本地时间还是从服务器取的呢,毕竟客户端本地时间可以修改
    lgh06
        18
    lgh06  
       2016-10-19 10:28:46 +08:00
    @ooTwToo 我想到了 Google Authenticator ……将军令之类的也是一样…… 或者用用 json web token 之类的 接口做下验证。 http://jwt.io
    ooTwToo
        19
    ooTwToo  
       2016-10-19 10:30:34 +08:00
    @alouha 对,客户端。 你可以再改变一下验证规则,增加一下破解难度。
    比如: UA 、 Referer ;再将 sign 算法更改一下,我看乐视 API 的做法是:将 secretkey 之外的公共参数升序排序,然后再 MD5 ,这样增加了爬虫的成本。

    接触这方面不久,经验不足,如有见解,欢迎言论。
    BOYPT
        20
    BOYPT  
       2016-10-19 10:33:55 +08:00
    (我看标题第一个想法是,返回图片呀
    qwer1234asdf
        21
    qwer1234asdf  
       2016-10-19 11:26:40 +08:00
    encryption + base64 encode ?
    TingHaiJamiE
        22
    TingHaiJamiE  
       2016-10-19 12:50:54 +08:00
    这是反爬虫的问题吧,不如从版权方面考虑。
    yidinghe
        23
    yidinghe  
       2016-10-19 12:57:02 +08:00 via Android
    简单做法是,受控资源需要登录才能访问
    ooTwToo
        24
    ooTwToo  
       2016-10-19 13:59:07 +08:00
    @lgh06 请教一下,前后端完全分离,又该怎么做才能保证安全性呢? JWT 好像不支持 JavaScript
    samueldeng
        25
    samueldeng  
       2016-10-19 15:31:37 +08:00
    @ooTwToo

    个人理解的粗略框架:

    客户端: 服务器
    -------(username, password)-------->
    <------根据(usr,pwd)生成的 token----
    --------GET /foo/bar (附带 token)---->
    --------POST /bar/foo (附带 token)---->

    不过细化下来,还是有好多考究的地方。

    至于说,题主提到的反爬虫, 可以通过上述方案将验证解耦到“登录验证”这边,发现有异常请求,封停 username,password 。
    否则, Web 技术确实无法保证绝对的安全性。
    ihuotui
        26
    ihuotui  
       2016-10-19 15:38:09 +08:00
    加 token , token 请求次数限制,根据统计正常的请求次数,然后设置一个伐值,超出后限制每小时请求数,请求的数据的 id 变为无规律,防止爬数据。感觉就跟传统的页面防止爬虫一样。
    wizardoz
        27
    wizardoz  
       2016-10-19 15:44:53 +08:00
    认证啊
    接口暴露出来不等于数据暴露出来
    wizardoz
        28
    wizardoz  
       2016-10-19 15:52:09 +08:00
    @ooTwToo 首先 javascript 有支持 jwt 的库 jsrsasign
    其次,jwt 用来做认证不需要前端支持,前端只要每次请求都在头部带上 jwt 的 token 就可以了,服务端自会处理.
    只有使用 jwt 包做数据加密传输的情况下才需要前端和服务器都支持 jwt.
    ooTwToo
        29
    ooTwToo  
       2016-10-19 16:43:26 +08:00
    @wizardoz OK ,大致知道了 JWT 的使用场景。就是说在前后端完全分离的情况下,只有某些模块才需要使用 JWT 来做认证,比如:订单、个人资料修改。那么用户登录功能该怎么做呢?标识用户登录的 token 是自己实现还是用 JWT?
    fangjinmin
        30
    fangjinmin  
       2016-10-19 16:55:14 +08:00
    RESTful 的接口,不想被外面调用的话,限制 IP 就是必要的了。

    如果想被外面有限的用户调用,那要增加对每个用户验证的机制。
    方法有很多,最简单的方法是双方约定一个密码,交互的数据进行加密,
    request 和 response 都只有双方能够解密对方的东西,
    传输时也加密( HTTPS ),还有一个是要防止有效的用户“作恶”,你必须
    对限制用户的可操作的数据的范围,不能 A 用户能操作 B 用户的数据。
    mingyun
        31
    mingyun  
       2016-10-19 23:53:56 +08:00
    楼上说的 jwt 各种语言都支持
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2931 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 13:27 · PVG 21:27 · LAX 06:27 · JFK 09:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.