您需要了解的有关App Store检查验证的知识(App Store收据)

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_datesubscription_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 // convert data to Dictionary and view purchases }.resume() } 

这是在iOS上验证支票的示例。 请记住用您的共享机密替换YOUR_SHARED_SECRET的值。


接收data ,将其转换为Dictionary


 DispatchQueue.main.async { if let data = data, let jsonData = try? JSONSerialization.jsonObject(with: data, options: .allowFragments){ // your non-consumable and non-renewing subscription receipts are in `in_app` array // your auto-renewable subscription receipts are in `latest_receipt_info` array } } 

解密的App Store收据示例


在这里,您可以看到带有自动续订订阅的应用程序中有两个事务的支票示例。


in_applatest_receipt_info什么latest_receipt_info


  • latest_receipt_info包含所有交易,包括自动续订购买的续订。 您应该只使用此数组。


  • in_app包含非in_app购买和不可续订订阅的交易。 您的自动续订订阅的第一笔交易也在此处重复。 耗材购买也会出现在in_app数组中,但是在开发人员完成交易后消失。



结论


Apphud的我们在便利的开源SDK中对App Store进行了验证,以检查具有自动续订订阅的应用程序。 Apphud还可以帮助您跟踪订阅状态,分析关键指标,自动为未订阅的用户提供折扣等等。 如果您在使用订阅时遇到麻烦,请免费试用我们的解决方案

Source: https://habr.com/ru/post/zh-CN472188/


All Articles