我想确认我对单个应用内购买的应用内结算购买,验证和消费流程有正确的概念。
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购买?
答案 0 :(得分:2)
我想回答我自己的问题,因为我想到了一种在不存储签名的情况下防止重放的方法。
重播问题可以通过存储每个签名然后检查唯一性来解决。
对于非消费品购买,开发人员有效负载可以消除这种需求,因为我们可以轻松地从令牌中提取(例如)用户ID。
对于消耗品购买,它更棘手,但我们仍然可以这样做:只需在令牌中存储一个total_purchased计数。我们可以从服务器验证此计数。 (在进行验证时,不要忘记锁定读写条目!)