Skip to content

搞英语 → 看世界

翻译英文优质信息和名人推特

Menu
  • 首页
  • 独立博客
  • 专业媒体
  • 名人推特
  • 邮件列表
  • 关于本站
  • Product Hunt
  • Visual Capitalist
  • Elon Musk
Menu

如何使用未记录的 Web API

Posted on 2022-03-11

你好!几天前,我写了一篇关于小型个人程序的文章,我提到使用“秘密”未记录的 API 会很有趣,您需要将 cookie 从浏览器中复制出来才能访问它们。

有几个人问如何做到这一点,所以我想解释一下,因为它非常简单。我们还将讨论可能出现的问题、道德问题,以及这如何适用于您未记录的 API。

例如,让我们使用 Google Hangouts。我选择这个不是因为它是最有用的例子(我认为有一个官方 API 会更实用),而是因为许多实际有用的站点是更容易受到滥用的较小站点。因此,我们将使用 Google Hangouts,因为我 100% 确定 Google Hangouts 后端的设计能够适应这种闲逛。

让我们开始吧!

第 1 步:在开发人员工具中寻找有希望的 JSON 响应

我首先访问https://hangouts.google.com ,在 Firefox 开发人员工具中打开网络选项卡并查找 JSON 响应。您也可以使用 Chrome 开发者工具。

这就是它的样子

网络标签.png

如果请求在“类型”列中显示“json”,则该请求是一个很好的候选者”

我不得不环顾四周,直到发现一些有趣的东西,但最终我找到了一个“人”端点,它似乎返回了有关我的联系人的信息。听起来很有趣,让我们来看看。

第 2 步:复制为 cURL

接下来,我右键单击我感兴趣的请求,然后单击“复制”->“复制为 cURL”。

然后我将curl命令粘贴到我的终端中并运行它。这就是发生的事情。

 $ curl 'https://people-pa.clients6.google.com/v2/people/?key=REDACTED' -X POST ........ (a bunch of headers removed) Warning: Binary output can mess up your terminal. Use "--output -" to tell Warning: curl to output it to your terminal anyway, or consider "--output Warning: <FILE>" to save to a file.

你可能会想——这很奇怪,这个“二进制输出会弄乱你的终端”错误是什么?这是因为默认情况下,浏览器会向服务器发送Accept-Encoding: gzip, deflate header 以获取压缩输出。

我们可以通过将输出传递到gunzip来解压缩它,但我发现不发送该标头更简单。所以让我们删除一些不相关的标题。

第 3 步:删除不相关的标题

这是我从浏览器获得的完整curl命令行。这里有很多!我首先使用反斜杠 ( \ ) 拆分请求,以便每个标头位于不同的行上,以便于使用:

 curl 'https://people-pa.clients6.google.com/v2/people/?key=REDACTED' \ -X POST \ -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0' \ -H 'Accept: */*' \ -H 'Accept-Language: en' \ -H 'Accept-Encoding: gzip, deflate' \ -H 'X-HTTP-Method-Override: GET' \ -H 'Authorization: SAPISIDHASH REDACTED' \ -H 'Cookie: REDACTED' -H 'Content-Type: application/x-www-form-urlencoded' \ -H 'X-Goog-AuthUser: 0' \ -H 'Origin: https://hangouts.google.com' \ -H 'Connection: keep-alive' \ -H 'Referer: https://hangouts.google.com/' \ -H 'Sec-Fetch-Dest: empty' \ -H 'Sec-Fetch-Mode: cors' \ -H 'Sec-Fetch-Site: same-site' \ -H 'Sec-GPC: 1' \ -H 'DNT: 1' \ -H 'Pragma: no-cache' \ -H 'Cache-Control: no-cache' \ -H 'TE: trailers' \ --data-raw 'personId=101777723309&personId=1175339043204&personId=1115266537043&personId=116731406166&extensionSet.extensionNames=HANGOUTS_ADDITIONAL_DATA&extensionSet.extensionNames=HANGOUTS_OFF_NETWORK_GAIA_GET&extensionSet.extensionNames=HANGOUTS_PHONE_DATA&includedProfileStates=ADMIN_BLOCKED&includedProfileStates=DELETED&includedProfileStates=PRIVATE_PROFILE&mergedPersonSourceOptions.includeAffinity=CHAT_AUTOCOMPLETE&coreIdParams.useRealtimeNotificationExpandedAcls=true&requestMask.includeField.paths=person.email&requestMask.includeField.paths=person.gender&requestMask.includeField.paths=person.in_app_reachability&requestMask.includeField.paths=person.metadata&requestMask.includeField.paths=person.name&requestMask.includeField.paths=person.phone&requestMask.includeField.paths=person.photo&requestMask.includeField.paths=person.read_only_profile_info&requestMask.includeField.paths=person.organization&requestMask.includeField.paths=person.location&requestMask.includeField.paths=person.cover_photo&requestMask.includeContainer=PROFILE&requestMask.includeContainer=DOMAIN_PROFILE&requestMask.includeContainer=CONTACT&key=REDACTED'

起初,这似乎是大量的东西,但在这个阶段你不需要考虑它的任何含义。您只需要删除不相关的行。

我通常只是通过反复试验找出可以删除哪些标头——我一直删除标头,直到请求开始失败。一般来说,您可能不需要Accept* 、 Referer 、 Sec-* 、 DNT 、 User-Agent和缓存标头。

在此示例中,我能够将请求缩减为:

 curl 'https://people-pa.clients6.google.com/v2/people/?key=REDACTED' \ -X POST \ -H 'Authorization: SAPISIDHASH REDACTED' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -H 'Origin: https://hangouts.google.com' \ -H 'Cookie: REDACTED'\ --data-raw 'personId=101777723309&personId=1175339043204&personId=1115266537043&personId=116731406166&extensionSet.extensionNames=HANGOUTS_ADDITIONAL_DATA&extensionSet.extensionNames=HANGOUTS_OFF_NETWORK_GAIA_GET&extensionSet.extensionNames=HANGOUTS_PHONE_DATA&includedProfileStates=ADMIN_BLOCKED&includedProfileStates=DELETED&includedProfileStates=PRIVATE_PROFILE&mergedPersonSourceOptions.includeAffinity=CHAT_AUTOCOMPLETE&coreIdParams.useRealtimeNotificationExpandedAcls=true&requestMask.includeField.paths=person.email&requestMask.includeField.paths=person.gender&requestMask.includeField.paths=person.in_app_reachability&requestMask.includeField.paths=person.metadata&requestMask.includeField.paths=person.name&requestMask.includeField.paths=person.phone&requestMask.includeField.paths=person.photo&requestMask.includeField.paths=person.read_only_profile_info&requestMask.includeField.paths=person.organization&requestMask.includeField.paths=person.location&requestMask.includeField.paths=person.cover_photo&requestMask.includeContainer=PROFILE&requestMask.includeContainer=DOMAIN_PROFILE&requestMask.includeContainer=CONTACT&key=REDACTED'

所以我只需要 4 个标头: Authorization 、 Content-Type 、 Origin和Cookie 。这更易于管理。

第 4 步:将其翻译成 Python

现在我们知道我们需要什么标头,我们可以将curl命令转换为 Python 程序!这部分也是一个非常机械的过程,目标只是使用 Python 发送与使用 curl 完全相同的数据。

这就是它的样子。这与前面的curl命令完全相同,但使用 Python 的requests 。我还将很长的请求正文字符串分解为一个元组数组,以便更容易以编程方式使用。

 import requests import urllib data = [ ('personId','101777723'), # I redacted these IDs a bit too ('personId','117533904'), ('personId','111526653'), ('personId','116731406'), ('extensionSet.extensionNames','HANGOUTS_ADDITIONAL_DATA'), ('extensionSet.extensionNames','HANGOUTS_OFF_NETWORK_GAIA_GET'), ('extensionSet.extensionNames','HANGOUTS_PHONE_DATA'), ('includedProfileStates','ADMIN_BLOCKED'), ('includedProfileStates','DELETED'), ('includedProfileStates','PRIVATE_PROFILE'), ('mergedPersonSourceOptions.includeAffinity','CHAT_AUTOCOMPLETE'), ('coreIdParams.useRealtimeNotificationExpandedAcls','true'), ('requestMask.includeField.paths','person.email'), ('requestMask.includeField.paths','person.gender'), ('requestMask.includeField.paths','person.in_app_reachability'), ('requestMask.includeField.paths','person.metadata'), ('requestMask.includeField.paths','person.name'), ('requestMask.includeField.paths','person.phone'), ('requestMask.includeField.paths','person.photo'), ('requestMask.includeField.paths','person.read_only_profile_info'), ('requestMask.includeField.paths','person.organization'), ('requestMask.includeField.paths','person.location'), ('requestMask.includeField.paths','person.cover_photo'), ('requestMask.includeContainer','PROFILE'), ('requestMask.includeContainer','DOMAIN_PROFILE'), ('requestMask.includeContainer','CONTACT'), ('key','REDACTED') ] response = requests.post('https://people-pa.clients6.google.com/v2/people/?key=REDACTED', headers={ 'X-HTTP-Method-Override': 'GET', 'Authorization': 'SAPISIDHASH REDACTED', 'Content-Type': 'application/x-www-form-urlencoded', 'Origin': 'https://hangouts.google.com', 'Cookie': 'REDACTED', }, data=urllib.parse.urlencode(data), ) print(response.text)

我运行了这个程序,它工作了——它打印出一堆 JSON!万岁!

你会注意到我用REDACTED替换了一堆东西,那是因为如果我包含这些值,你可以访问我的帐户的 Google Hangouts API,这将是不好的。

我们完成了!

现在我可以修改 Python 程序来做任何我想做的事情,比如传递不同的参数或解析输出。

我不会用它做任何有趣的事情,因为我实际上根本对使用这个 API 不感兴趣,我只是想展示一下这个过程是什么样子的。

但是我们得到了一堆你绝对可以用它来做点什么的 JSON。

这基本上总是有效的

你们中的一些人可能想知道——你能一直这样做吗?

答案基本上是肯定的——浏览器并不神奇!浏览器发送到后端的所有信息都只是 HTTP 请求。因此,如果我复制浏览器发送的所有 HTTP 标头,后端实际上无法判断请求不是由我的浏览器发送的,而是由随机 Python 程序发送的。

当然,我们删除了浏览器发送的一堆标头,因此理论上后端可以知道,但通常他们不会检查。

既然我们已经了解了如何使用此类未记录的 API,让我们来谈谈可能出错的一些事情。

问题 1:过期的会话 cookie

这里的一个大问题是我正在使用我的 Google 会话 cookie 进行身份验证,所以只要我的浏览器会话过期,这个脚本就会停止工作。

这意味着这种方法不适用于长时间运行的程序(我想使用真正的 API),但如果我只需要快速抓取一点数据作为 1-time 的东西,它可以很好地工作!

问题2:滥用

如果我使用的是小型网站,我的小 Python 脚本有可能会取消他们的服务,因为它处理的请求比他们能够处理的要多得多。因此,当我这样做时,我会尽量保持尊重,不要过快提出太多要求。

这一点尤其重要,因为许多没有官方 API 的站点都是资源较少的较小站点。

在这个例子中,这显然不是问题——我想我在写这篇博文时总共向 Google Hangouts 后端发出了 20 个请求,他们绝对可以处理。

此外,如果您过度使用您的帐户凭据访问 API 并导致问题,您可能(非常合理地)暂停您的帐户。

我还坚持下载属于我的或打算公开访问的数据——我不是在寻找漏洞。

请记住,任何人都可以使用您未记录的 API

我认为最重要的是要知道这实际上并不是如何使用其他人未记录的 API。这很有趣,但它有很多限制,我实际上并不经常这样做。

了解任何人都可以对您的后端 API 执行此操作更为重要!每个人都有开发者工具和网络标签,很容易看到你传递给后端的参数并改变它们。

因此,如果任何人都可以通过更改某些参数来获取其他用户的信息,那就不好了。我认为大多数构建公开可用 API 的开发人员都知道这一点,但我之所以提到它,是因为每个人都需要在某个时候第一次学习它 🙂

来源: https://jvns.ca/blog/2022/03/10/how-to-use-undocumented-web-apis/

发表回复 取消回复

要发表评论,您必须先登录。

本站文章系自动翻译,站长会周期检查,如果有不当内容,请点此留言,非常感谢。
  • Bob Nystrom (1)
  • Dan Wang (1)
  • Joel on Software (1)
  • John Resig (1)
  • Laurence Gellert's Blog (1)
  • Matt Might's blog (3)
  • News Letter (191)
  • Philip Walton (1)
  • Pivotal (1)
  • Sam Julien (1)
  • Scott Hanselman's Blog (2)
  • Tom's blog (1)
  • Wait But Why (1)
  • 英文媒体 (36,629)
    • Ars Technica (2,472)
    • Daily Infographic (285)
    • Engadget (5,715)
    • Enonomist (77)
    • FlowingData (254)
    • Hacker News (773)
    • Hacker News Daily (314)
    • Hacker Noon (125)
    • Harvard Health (150)
    • KK – Cool Tools (213)
    • KK – Recomendo (263)
    • Make Use Of (158)
    • NASA Astronomy Picture (268)
    • Product Hunt (7,505)
    • Psyche (220)
    • Quanta Magazine (187)
    • Science current issue (536)
    • Sidebar (1,033)
    • Singularity HUB (278)
    • TechCrunch (9,045)
    • The Practical Developer (99)
    • The Verge (6,278)
    • Visual Capitalist (381)
  • 英文推特 (17,682)
    • Bill Gates (342)
    • Brett Winton (1,333)
    • Cathie Wood (303)
    • Durov's Channel (25)
    • Elon Musk (5,422)
    • GeekWire (2,868)
    • Hunter Walk (55)
    • Mark Gurman (1,061)
    • Naval (699)
    • Parag Agrawal (52)
    • Ray Dalio (1,045)
    • Riccardo Mori (16)
    • Steph Smith (2,269)
    • Tim Cook (169)
    • Vitalik Buterin (2,023)
  • 英文独立博客 (3,801)
    • A learning a day (327)
    • A Smart Bear (2)
    • AddyOsmani.com (10)
    • Adwyat Krishna (29)
    • Ahmad Shadeed (2)
    • Alex Turek (3)
    • All Poetry (1)
    • All That is Solid (49)
    • André Staltz (2)
    • arxivblog (37)
    • Astral Codex Ten (15)
    • Atoms vs Bits (26)
    • AVC (40)
    • Basic Apple Guy (41)
    • Ben Thompson (13)
    • Benedict Evans (8)
    • Blog – storytelling with data (43)
    • Built For Mars (11)
    • Caleb Porzio (1)
    • Cameron Sun (2)
    • Christian Heilmann (39)
    • Christopher C (3)
    • Chun Tian (binghe) (1)
    • Codrops (16)
    • Cold Takes (16)
    • Dan Luu (1)
    • Daniel Lemire's blog (51)
    • David Amos (23)
    • David Perell (6)
    • David Walsh Blog (36)
    • Derek Sivers (28)
    • Desvl (14)
    • Devon's Site (5)
    • Digital Inspiration (26)
    • DKB Blog (4)
    • Douglas Vaghetti (12)
    • dropsafe (56)
    • DSHR (37)
    • Dunk (5)
    • DYNOMIGHT (38)
    • eagereyes (7)
    • Endless Metrics (135)
    • Entitled Opinions (8)
    • Exception Not Found (6)
    • Experimental History (21)
    • Farnam Street (6)
    • Fed Guy (10)
    • Felix Krause (3)
    • Florent Crivello (2)
    • Free Mind (7)
    • Full Stack Economics (40)
    • Funny JS (3)
    • Future A16Z (47)
    • Glassnode Insights (55)
    • Human Who Codes (4)
    • Infographics – Cool Infographics (10)
    • Information is Beautiful (11)
    • Irrational Exuberance (40)
    • Jacob Kaplan-Moss (13)
    • Jakob Greenfeld (44)
    • James Sinclair (3)
    • Jason Fried (17)
    • Jeff Kaufman (178)
    • John's internet house (31)
    • Johnny Rodgers (4)
    • Julia Evans (25)
    • Julian.com (2)
    • Kalzumeus (1)
    • Kevin Cox (10)
    • Kevin Norman (3)
    • KK – The Technium (50)
    • Krishna (7)
    • Lee Robinson (5)
    • Lines and Colors (51)
    • Lyn Alden – Investment Strategy (3)
    • Martin Fowler (28)
    • More To That (13)
    • Morgan Housel (76)
    • My Super Secret Diary (30)
    • Naval Blog (3)
    • Neckar's New Money (76)
    • Nick Whitaker (4)
    • Nicky's New Shtuff (1)
    • nutcroft (10)
    • Paul Graham (2)
    • Paul Graham: Essays (2)
    • Penguin Random House (66)
    • Phoenix's island (1)
    • Prof Galloway (35)
    • Python Weekly (30)
    • Rachel (33)
    • Real Life (34)
    • Sasha (63)
    • Science & technology (122)
    • Sébastien Dubois (6)
    • Secretum Secretorum (13)
    • Seth's Blog (147)
    • Shu Ding (3)
    • SignalFire (9)
    • Simon Willison's Weblog (167)
    • Simons Foundation (85)
    • SLIME MOLD TIME MOLD (23)
    • Slyar Home (8)
    • Spencer Greenberg (10)
    • Stay SaaSy (11)
    • Stephen Malina (4)
    • Stephen Wolfram Writings (2)
    • Strange Loop Canon (23)
    • Stratechery (10)
    • Tech Notes (11)
    • The Commonplace (29)
    • The Generalist (2)
    • The Intrinsic Perspective (30)
    • The Latest in Hearing Health | HeardThat (8)
    • The Mad Ned Memo (2)
    • The Rabbit Hole (37)
    • TLDR Newsletter (81)
    • Tomasz Tunguz (91)
    • Tony Kulesa (2)
    • Troy Hunt (58)
    • Tychlog (1)
    • Uncharted Territories (57)
    • Visualising Data (9)
    • Weichen Liu (20)
    • What's New (55)
    • Works in Progress (1)
    • Workspaces (32)
    • Writing (8)
    • Xe's Blog (35)
    • xkcd.com (117)
    • Yihui Xie (13)
    • Zoran Jambor (11)
©2023 搞英语 → 看世界 | Design: Newspaperly WordPress Theme