Google Play应用内结算/应用内购买:购买,验证和消费流程?

时间:2015-01-04 01:47:27

标签: oauth-2.0 google-play google-play-services in-app-billing

我想确认我对单个应用内购买的应用内结算购买,验证和消费流程有正确的概念。

1)用户在我的应用中订购产品,让我们说gems_9。 (9个宝石)他们查询Google Play服务器并输入密码。 Google Play会记录订单。

2)我的服务器然后使用openssl_verify to verify the transaction is valid and has the correct values。 E.G:

function validate_google_play_signature ($receipt, $signature, $public_key) {
 // Create an RSA key compatible with openssl_verify from our Google Play signature.
 $key = "-----BEGIN PUBLIC KEY-----\n" . chunk_split($public_key, 64,"\n") . '-----END PUBLIC KEY-----';
 $key = openssl_get_publickey ($key);

 // Signature should be in binary format, but it comes as BASE64.
 $signature = base64_decode($signature);

 // Verify the signature.
 $result = openssl_verify ($receipt, $signature, $key, OPENSSL_ALGO_SHA1);
 return ($result == 1);
}

3)我自己的服务器现在将验证购买是否尚未消耗。对于访客:
https://developers.google.com/android-publisher/api-ref/purchases/products/get
Get android subscription status, failed with 403

3b)我的服务器为用户提供应用内货币。

4)好的,很好,购买已经过验证。现在我需要消耗它。应用 本身 会消耗此商品。

问:什么阻止用户黑客攻击我的应用,不消费购买,并将相同的订单发送到我的服务器?在这种情况下,我是否需要为每个用户存储和测试令牌,这是唯一的方法吗?

有没有办法通过oauth购买?

1 个答案:

答案 0 :(得分:2)

我想回答我自己的问题,因为我想到了一种在不存储签名的情况下防止重放的方法。

重播问题可以通过存储每个签名然后检查唯一性来解决。

对于非消费品购买,开发人员有效负载可以消除这种需求,因为我们可以轻松地从令牌中提取(例如)用户ID。

对于消耗品购买,它更棘手,但我们仍然可以这样做:只需在令牌中存储一个total_purchased计数。我们可以从服务器验证此计数。 (在进行验证时,不要忘记锁定读写条目!)