StackOverflow仍然存在许多有关验证App Store检查的问题,因此我们决定以问答形式撰写有关此主题的文章。

什么是App Store检查?
这是PKCS#7格式的加密文件,其中包含有关应用程序中所有购买的信息。 它位于应用程序捆绑包中,可以通过调用以下Bundle.main.appStoreReceiptURL
轻松获得: Bundle.main.appStoreReceiptURL
。
总是有这个文件吗?
如果该应用程序是从App Store下载的,则总是。 而且,如果它是通过Xcode或Testflight安装的,则最初该应用程序没有沙盒检查,直到第一次购买或恢复该检查。
“验证支票”是什么意思?
这意味着解密文件,接收JSON日期,并验证用户进行的购买。 您可以在本地执行此操作,也可以向Apple发送请求。
在什么情况下,开发人员需要验证支票?
验证刚刚完成的购买。
当许多人越狱时,这很重要:有一些伪造支票的工具。 现在,这个问题已经不再是尖锐的了,因为越狱已经变得非常罕见。
恢复购买时。
如果用户重新安装您的应用程序或从其他设备启动,则必须授予他访问其已付费功能的权限。 解密了App Store支票后,您可以了解是否购买了应用内购买。
购买自动续订的订阅时。
确定当前的订阅状态和到期日期。
验证期间可以恢复哪些购买?
应用内购买有4种类型:
- 消耗品购买
- 非消费品购买
- 非续订订阅
- 自动续订订阅
您可以恢复除已花费的购买之外的所有内容。 例如,其中包括应用程序中的硬币-您可以随意购买多次。 您必须将当前的硬币数量保存在服务器上的用户处。
存在哪些验证方法?
其中有三个:
- 使用OpenSSL进行本地验证,
- Apple直接从iOS设备进行按需验证,
- Apple使用您的服务器进行按需验证。
哪种验证方法更好?
本地验证是复杂的,需要大量时间和精力来实施。 您还需要将OpenSSL库添加到您的项目中。 在某些情况下,您将必须更新支票。
Apple不建议在iOS设备本身上检查支票。 这是不安全的:可以通过中间人攻击来拦截请求。
最好在服务器上验证检查。 此外,Apple有时会在其中添加新字段,例如grace_period_expires_date
和subscription_group_identifier
。 在我们的服务器上,我们可以快速进行更改而无需更新应用程序。 只需更改iOS设备上的系统时间,就可以轻松地欺骗前两种验证方法。
共享秘密有什么用?
这是一条特殊的密钥行,对于用自动续签的购买解密支票是必需的。 Apple在向Apple发出的HTTPS请求中将共享密钥用作参数。
在哪里获取共享秘密?
转到App Store Connect,打开应用程序,转到“ 功能”选项卡,在“ 内置购买”部分,您将看到应用程序按钮的共享密钥 。 生成新密钥(如果尚未生成)。
验证支票的示例代码
func validateReceipt(){ #if DEBUG let urlString = "https://sandbox.itunes.apple.com/verifyReceipt" #else let urlString = "https://buy.itunes.apple.com/verifyReceipt" #endif guard let receiptURL = Bundle.main.appStoreReceiptURL, let receiptString = try? Data(contentsOf: receiptURL).base64EncodedString() , let url = URL(string: urlString) else { return } let requestData : [String : Any] = ["receipt-data" : receiptString, "password" : "YOUR_SHARED_SECRET", "exclude-old-transactions" : false] let httpBody = try? JSONSerialization.data(withJSONObject: requestData, options: []) var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("Application/json", forHTTPHeaderField: "Content-Type") request.httpBody = httpBody URLSession.shared.dataTask(with: request) { (data, response, error) in
这是在iOS上验证支票的示例。 请记住用您的共享机密替换YOUR_SHARED_SECRET
的值。
接收data
,将其转换为Dictionary
:
DispatchQueue.main.async { if let data = data, let jsonData = try? JSONSerialization.jsonObject(with: data, options: .allowFragments){
解密的App Store收据示例
在这里,您可以看到带有自动续订订阅的应用程序中有两个事务的支票示例。
in_app
和latest_receipt_info
什么latest_receipt_info
?
结论
Apphud的我们在便利的开源SDK中对App Store进行了验证,以检查具有自动续订订阅的应用程序。 Apphud还可以帮助您跟踪订阅状态,分析关键指标,自动为未订阅的用户提供折扣等等。 如果您在使用订阅时遇到麻烦,请免费试用我们的解决方案 。