我最近遇到了这个应用程序 Purchase Apps,它能够在我使用我的 google 帐户登录后以某种方式检索我在 google play 中支付的应用程序。
我试图找出它是如何完成的,因为我想构建一个类似的应用程序,但是对于下载的免费应用程序。
但是,即使在通过 the entire list of APIs 之后,我也找不到用于检索该信息的 OAuth API 范围。
https://i.stack.imgur.com/cc8qKl.jpg
编辑:我在这个问题上提出了新的赏金,正如我问过的关于 here 的类似问题所建议的那样,因为在这里和那里我没有看到关于如何做到这一点的真正答案,以及什么可以完成它。
我想将问题细化为多个部分:
可用于获取已购买应用程序信息的 API 是什么?我在哪里可以读到它?请展示一个完整的、有效的例子来说明如何做到这一点。它可以做得更多吗?也许执行搜索?也许显示已安装的免费应用程序?也许是安装和卸载它们的时间?以及这些应用程序的类别?使用这个 API 有什么特殊要求吗?
编辑:我为此付出了最大的赏金,因为无论我阅读和尝试了多少,我仍然无法创建一个可以从 Play 商店查询用户曾经下载过的应用程序的 POC(名称、包名称、安装和/或删除日期、图标 URL、价格...),包括付费和免费应用程序。
如果有人找到了一个工作示例,请展示它是如何完成的,并展示您是如何找到它的(文档或任何导致您找到解决方案的东西)。我在任何地方都找不到它,而且这里的当前解决方案对我来说太模糊了,无法开始。
Purchase Apps
apk 文件。它从未使用任何 api 来获取已购买应用程序的列表。它的方法和我们知道的一样是解析play store网页的html内容。下面是这段代码的一个片段:hastebin.com/uceyavurij.js
Purchased Apps
提供的所有信息都可以从 Playstore 网页内容中检索到。不幸的是,我无法从 google play 购买应用程序。如果您与我分享一个已购买应用程序的帐户,我可以为您开发示例代码。
问题已解决。该漏洞利用已关闭。
由于登录的是 Android 的预览版,我们将关闭此错误。如果问题在最新的公开版本 (Android Q) 中仍然相关且可重现,请捕获错误报告并将错误记录在 https://source.android.com/setup/contribute/report-bugs。如果在接下来的 14 天内未收到回复,此问题将被关闭。感谢您的理解。
最近更新:
这是一个错误,Google 将在下一次更新中解决它。
我们已将此问题推迟到将来的版本中考虑。感谢您抽出宝贵时间让 Android 变得更好
这个答案已经变成了一个想法的集合,并被编辑以在评论中包含来自讨论的信息。
androidmarket
api 将是开发人员编写的自定义 api。它不向公众开放。
在评论中解决您的疑虑。开发人员将利用 Android Developer 和 Google 提供的当前 API 来创建一个管理所有这些的项目。
至于访问 Full Account Access
,我不确定这些开发人员究竟是如何做到这一点的。
我建议使用 AccountManager,它是 android.accounts 的一部分,可以访问凭据和方法 getUserData。帐户管理员有权访问密码,并能够创建和删除帐户。这可能与 Content Provider 一起使用
请参阅Udinic/SyncAdapter Authentication。
要回复您的评论:
该博客应该可以帮助您入门。 Write your own Android Authenticator。
这些应用程序实际上是如何工作的,我不能告诉你。它们也可能有不同的实现(除非它们是幕后的协作努力,否则它们肯定会有所不同)。
一猜。首先将 GoogleSignInAccount 与 com.google.android.gms.auth.api.signin 一起使用。
scope 有一个定义,用于确定授予应用程序的权限范围。
使用 requestScopes(),
public static final String PROFILE
.../ 它让您的网络应用程序可以通过无线方式访问 Android 应用程序安装。
对于 example:
GoogleSignInOptions gso =
new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail().
.requestScopes(new Scope("https://www.googleapis.com/auth/contacts.readonly"))
.build();
如果可以获得完全访问权限,则可以找到帐户持有人使用的所有应用程序的列表,并将其与设备上的内容进行比较。
Package Manager 将检索设备上当前安装的所有应用程序的列表。
PackageInfo 提供有关应用程序的详细信息。
INSTALL_REASON_USER 还将过滤掉用户主动安装的应用程序。
您可能想查看 com.google.firebase.appindexing 和 Log User Actions。可以跟踪不同的actions。
用户帐户历史记录位于 https://myactivity.google.com/myactivity。
OAuth 2.0 Playground 是一个有用的链接。
这个使用节点的 github 存储库 node-google-play 是最新的,将调用 Google Play API。与用作“非官方”api 的存档 android-market-api 一样,用于查询市场。
应用程序 1
app claims 使用以下权限:
2.1.8版本可以访问: $ 应用内购买 其他从互联网接收数据 查看网络连接 完全网络访问 使用设备上的帐户 防止设备休眠 读取谷歌服务配置
值得注意的是,该应用程序在进行基本安装时不会设置任何权限。我无法使用任何功能,因为我没有付费应用程序。因此,对于初始搜索 - 不需要权限,这表明该应用程序无权访问我的帐户。
我检查了权限 - 没有设置。因此,唯一需要做的就是接受弹出窗口,如您的问题中所示。
https://i.stack.imgur.com/SVhst.png
应用程序 2
您提到的另一个执行相同操作的应用程序更预先了解正在访问的内容。
安全/隐私声明 第一次运行此应用程序时,它会要求您获得 Google 帐户的完全权限。不幸的是,这是访问所需信息的唯一方法。不会存储任何个人信息,不会与此应用程序的开发者共享有关您的应用程序的信息,也不会与任何第三方共享。一切都只保存在您的手机上。
https://i.stack.imgur.com/Y4DIn.png
我在 this blog post 中详细介绍了这些应用程序,这是一个大学的顶点项目(没有金钱收益)。我倾向于认为这是 API 中的一个漏洞,而不是谷歌设计的状态,因为除了开发者自己的应用程序之外,没有任何 API 调用来获取应用程序的购买。我假设这是一个零日漏洞,在这种情况下,没有合法的方式来访问这些信息。
对于这些应用程序之一(我的付费应用程序),在检查网络流量后,很明显它确实使用商店的帐户页面来检索付费应用程序列表。现在,它使用的机制与 Google Chrome 当前使用的机制相同,并且 Pokemon GO 据说在某个时间点使用过。
简而言之,这样做的步骤如下:
登录:上述程序的第一步是让用户登录并访问用户的访问令牌。为此,它使用 android.accounts.AccountManager.getAuthToken() 方法。 (查看更多:AccountManager) 但是,对于令牌范围,需要 oauth2:https://www.google.com/accounts/OAuthLogin。值得注意的是,根据 Google 的 OAth2 文档,此范围无效;但是,它似乎是 Google OAuth v1 的有效范围。将新检索到的访问令牌转换为 ubertoken:现在,实际上 ubertoken 应该做什么是未知的,也没有关于它的官方文档。然而,它被广泛用于 chrome 浏览器登录用户。这是通过请求 https://accounts.google.com/OAuthLogin?source=ChromiumBrowser&issueuberauth=1 页面来完成的。将 ubertoken 转换为网站会话:稍后,使用新创建的 ubertoken 可以使用 https://accounts.google.com/MergeSession API 端点获取网站会话。在这一步之后,该应用程序基本上能够加载您可以在登录时使用浏览器打开的所有个人页面;除了一些特殊页面,包括付款设置。检索付费应用列表:请求并解析 https://play.google.com/store/account 页面。
以下是“Packet Capture”捕获的应用程序流量:
https://i.stack.imgur.com/zuB3n.jpg
https://i.stack.imgur.com/sc9gv.jpg
边注:
似乎这些端点都没有记录,因为它们主要由 Google 自己的程序使用,应该被视为内部的。因此,我强烈建议不要在您希望长时间运行的任何程序或代码中或在生产环境中使用它们。此外,这里也有一个坏消息,Google Play 的帐户页面似乎只列出了付费应用程序或特殊免费应用程序(尤其是 OEM 应用程序)。我将尝试找一些时间并深入研究其他应用程序。
有趣的文章:
Exploiting Google Chrome's OAuth2 Tokens
如果您有 root 访问权限,您可以访问 /data/data/com.android.vending/databases/library.db
OnePlus3T:/data/data/com.android.vending/databases
-rw-rw---- 1 u0_a2 u0_a2 229376 2018-12-26 18:01 library.db
该数据库包含所有信息,包括您下载了哪些应用程序、您购买了哪些应用程序,甚至您在哪个应用程序中完成了操作IAP
。
检查所有权表,它包含所有信息。
ownership (account STRING, library_id STRING, backend INTEGER, doc_id STRING, doc_type INTEGER, offer_type INTEGER, document_hash INTEGER, subs_valid_until_time INTEGER, app_certificate_hash STRING, app_refund_pre_delivery_endtime_ms INTEGER, app_refund_post_delivery_window_ms INTEGER, subs_auto_renewing INTEGER, subs_initiation_time INTEGER, subs_trial_until_time INTEGER, inapp_purchase_data STRING, inapp_signature STRING, preordered INTEGER, owned_via_license INTEGER, shared_by_me INTEGER, sharer_gaia_id TEXT, shareability INTEGER, purchase_time INTEGER, PRIMARY KEY (account, library_id, backend, doc_id, doc_type, offer_type))
处理非官方的 Google API 是非常复杂的领域。让它工作是可能的,但这就是我要说的。继续需要您自担风险。
您需要做的第一件事是获取 Google Play 身份验证令牌。这可以通过多种方式完成,但在购买的应用程序中是这样的:
public static String getAuthToken(Activity activity, String userEmail) {
AccountManager accountManager = AccountManager.get(activity);
Account userAccount = new Account(userEmail, "com.google");
Bundle options = new Bundle();
options.putBoolean("suppressProgressScreen", true);
String token;
try {
Bundle result = accountManager
.getAuthToken(userAccount, "androidmarket", options, activity, null, null)
.getResult();
token = result.getString("authtoken");
} catch (OperationCanceledException e) {
Log.d(TAG, "Login canceled by user");
return null;
} catch (IOException | AuthenticatorException e) {
Log.e(TAG, "Login failed", e);
return null;
}
return token;
}
这里有几点需要注意:
上面的代码必须异步运行。我推荐 RxJava,但 AsyncTask 可以工作。
您必须为要使用的帐户提供电子邮件。我将把细节留给你,但使用 AccountManager 相当容易。
获得身份验证令牌后,您现在可以访问任何 Google Play 商店端点。购买的应用程序使用的主要是 https://android.clients.google.com/fdfe/purchaseHistory
。您可能感兴趣的另一个是 https://android.clients.google.com/fdfe/details?doc=(package name)
(来自 APKfetch code)。 Here's a page with some more and some analysis. 如果您向这些 API 发出请求,则需要提供几个标头:
授权 - “GoogleLogin auth=(您的身份验证令牌)”
User-Agent - "Android-Finsky/6.4.12.C-all%20%5B0%5D%202744941 (api=3,versionCode=80641200,sdk=" + VERSION.SDK_INT + ",isWideScreen=0)";
X-DFE-Device-Id - 您设备的 Google 服务框架 ID,从 AdvertisingIdClient 获得。
X-DFE-Client-Id - “am-android-google”
Accept-Language - 设备的语言代码,例如“en”。
现在,您需要解析响应。这就是事情变得棘手的地方。这些 API 返回编码为 Protobuf 的消息,因此它本质上只是二进制数据,除非您有架构(当然,只有 Google 有)。理论上解决这个问题的一种方法是反编译 Google Play 商店应用程序并使用 JADX 之类的工具重用它们生成的 protobuf 模型。
不幸的是,我已经尝试过了,但它并没有真正起作用。 Protobuf 模型类对于标准反编译器来说太复杂了。您可以使用一个名为 PBTK 的工具。您最好在 Google Play Store 6.1.12 APK 上运行它,因为这是他们开始使用 ProGuard 之前的最后一个版本。请注意,该程序在其脚本中有两个错误需要在运行之前修复:将 gui.py 中的 'extracto'
更改为 'extractor'
并删除 第 500 行的断言语句>jar_extract.py。
现在,这应该将所有响应类输出为 .proto 文件。在 src/main 下创建一个名为 proto
的文件夹并将整个生成的“com”目录拖到其中。您可以删除不在 com/google/android/finsky/protos
下的所有内容。按照在线说明使用 Protobuf Lite 插件设置 Gradle。
当您想解析响应时,可以使用 ResponseWrapper 类,因为它们似乎都包含在该类之下。
我能带你到这里就差不多了。我很有可能弄错了其中的一部分; JADX 是你最好的朋友,因为了解应用程序在做什么的最好方法是查看它的代码。希望这有助于并快乐发展!
AccountManager
,您确定它仍然可用吗?我认为现在谷歌只提供使用 AccountPicker
的选项(如这里: stackoverflow.com/a/26888259/878126 )。但是我如何执行其余的?你测试过吗?它对你有用吗?请分享它的代码。这就是为什么我设置了一个赏金,看看它在行动......
您可以获取设备上所有已安装应用程序的软件包名称,然后从 google play 获取您在设备中找到的每个已安装软件包的信息,而无需访问用户帐户。有一些第三方或非官方 apis 通过获取应用程序包名称来获取 json 格式的 google play 应用程序详细信息。例如:https://42matters.com/ 然后使用收到的每个包裹的信息来查找免费包裹。
我有两个资源供您考虑,但首先,总而言之,不。 GOOGLE 没有 api 可以让你做你想做的事,因为这些指标没有存储在手机中,它们在 google play store 伺服器上,google 没有用于 play store 的官方 api。但是,您可以从这两个站点收集一些信息:
https://www.quora.com/Is-there-an-API-for-the-Google-Play-Storeenter link description here
这足以了解如何做到这一点。
首先,一个帐户下载了哪些应用程序的列表只能由该帐户引用。这可以通过游戏商店完成。由于您的应用程序将安装在该用户的手机上,因此这无关紧要……您在里面。
其次,您需要为 GOOGLE PLAY STORE 构建的第 3 方 API,那里有一些,请查看第一个链接。
使用您选择的 api,您将向 play 商店发送一个 get 请求,作为回报,您应该在大多数情况下收到一个要反序列化的 json 对象。
反序列化对象,您将拥有您的列表。您获得的列表将取决于您使用的端点,但这应该由/在 API 本身中解释。
祝你好运!