Cis*_*zko 2 python-3.x firebase firebase-app-distribution
我的主要目标是以编程方式下载从 firebase 应用程序分发分发给测试人员的应用程序。效果应该与在此处从应用程序分发中按指定版本上的“下载”按钮相同:
我尝试过使用Firebase REST API,但似乎只有用于列出指定应用程序的版本并上传版本的端点,没有下载选项。
我还检查了支持 firebase 存储的firebase,但是您可以在没有存储的情况下添加应用程序版本,因此我认为它不是存储它们的位置。
“下载”按钮生成的下载 URL 遵循以下模式https://firebaseappdistribution.googleapis.com/app-binary-downloads/firebase-app-distro/app-binaries/[PROJECT_ID]/[APP_ID]/e4faf167-0e3d-4b1a-82dd-44811c0b5e43.apk?token=[TOKEN]。之后的部分[APP_ID]标识了应用程序,但我无法找到它来自哪里。
是否有可能以这种方式下载应用程序?还有其他方法可以下载该应用程序吗?
经过几天的努力,我终于找到了解决办法!这绝对不好,并且正在使用 Firebase 内部 API,而该 API 在外部实际上并不可用。我的解决方案使用两个会话。
第一个是来自 的授权会话google.auth.transport.requests.AuthorizedSession,凭据按照文章中的方式生成: https: //developers.google.com/docs/api/quickstart/python,然后传递到AuthorizedSession。此会话正在使用记录的firebase REST API,例如获取应用程序的所有已发布版本。
第二个用于内部 Firebase API,需要来自浏览器会话的 cookie。为了获取 cookie,我必须登录 firebase 并导航到应用程序分发来下载应用程序。我打开开发控制台(F12)并观察“网络”选项卡。Firebase 正在发出 2 个下载应用程序的请求。第一个是获取下载 URL,第二个是调用上一个请求返回的 URL。两个请求中的第一个请求的地址类似于https://firebaseappdistribution-pa.clients6.google.com/v1/{app_name}:getLatestBinary?alt=json&key={api_key}。app_name来自获取所有应用程序版本时经过身份验证的会话。api_key可以从浏览器 URL 或第一个请求参数中复制。发送带有这些参数的 GET 请求是行不通的,它还需要 cookies 和 headers。
足够的标头是:
{
'origin': 'https://console.firebase.google.com',
'referer': 'https://console.firebase.google.com/',
'x-goog-authuser': '<has to be copied from the first request from browser>'
}
Run Code Online (Sandbox Code Playgroud)
当涉及到 cookie 时,事情稍微复杂一些,请求需要以下 cookie:“APISID”、“HSID”、“SAPISID”、“SID”和“SSID”。我从第一个请求中复制了它们。那么所缺少的就是一个额外的 cookie:“SAPISIDHASH”,感谢这个答案,我已经在 python 中创建了我的实现:
def calculate_sapisid_hash(cookies):
"""Calculates SAPISIDHASH based on cookies. Required in authorization to download apk from firebase"""
epoch = int(time())
sha = sha1(' '.join([str(int(epoch)), cookies['SAPISID'], 'https://console.firebase.google.com']).encode())
return f'SAPISIDHASH {int(epoch)}_{sha.hexdigest()}'
Run Code Online (Sandbox Code Playgroud)
最后,通过在 cookie 中添加“SAPISIDHASH”,我们可以在第一个 URL 上发送 GET 请求,并获得包含“fileURL”和“fileSize”的有效响应。有了“fileURL” ,我们就可以用requests.get//保存最终文件,因为不需要额外的授权wgetcurl
| 归档时间: |
|
| 查看次数: |
1580 次 |
| 最近记录: |