在应用帐单签名验证中

时间:2014-11-20 04:27:04

标签: android in-app-billing developer-payload

我对开发人员有效负载提出了问题,我一直在阅读该文档,但仍然发现自己很难理解我仍然不了解的验证开发负载:

boolean verifyDeveloperPayload(Purchase p) {
        String payload = p.getDeveloperPayload();
        /*
         * TODO: verify that the developer payload of the purchase is correct. It will be
         * the same one that you sent when initiating the purchase.
         *
         * WARNING: Locally generating a random string when starting a purchase and
         * verifying it here might seem like a good approach, but this will fail in the
         * case where the user purchases an item on one device and then uses your app on
         * a different device, because on the other device you will not have access to the
         * random string you originally generated.
         *
         * So a good developer payload has these characteristics:
         *
         * 1. If two different users purchase an item, the payload is different between them,
         *    so that one user's purchase can't be replayed to another user.
         *
         * 2. The payload must be such that you can verify it even when the app wasn't the
         *    one who initiated the purchase flow (so that items purchased by the user on
         *    one device work on other devices owned by the user).
         *
         * Using your own server to store and verify developer payloads across app
         * installations is recommended.
         */
        return true;
    }

如果我的代码是

public void onClick(View v) {
    String item1;
    // TODO Auto-generated method stub
     switch(v.getId()) {
        case R.id.button1: {
            /* TODO: for security, generate your payload here for verification. See the comments on
             *        verifyDeveloperPayload() for more info. Since this is a SAMPLE, we just use
             *        an empty string, but on a production app you should carefully generate this. */

            item1 = "item1";
            String payload = email+item1;

            mHelper.launchPurchaseFlow(this, SKU_2006, RC_REQUEST,
                    mPurchaseFinishedListener, payload);
            break;
            }
         }

}

来自boolean verifyDeveloperPayload的String有效负载是否等于来自onClick方法的String有效负载?

我如何以及在何处比较有效载荷?

1 个答案:

答案 0 :(得分:7)

根据android文档here,声明

  

第五个参数包含一个'developer payload'字符串   用于发送有关订单的补充信息(可以是   空字符串)。通常,这用于传入字符串标记   唯一标识此购买请求。如果指定字符串   价值,Google Play会随购买一起返回此字符串   响应。随后,当您对此次购买进行查询时,   Google Play会将此字符串与购买详情一起返回。

     

安全建议:最好传入一个字符串   帮助您的应用程序识别进行购买的用户,以便   您可以稍后验证这是合法的购买   用户。对于耗材,您可以使用随机生成的字符串,   但对于非消耗品,您应该使用唯一的字符串   识别用户。

因此,对于产品ID SKU_2006 ,如果您使用String payload = email+item1;启动了购买流程,则Google Play将在响应中返回相同的有效内容,因此您可以在此处获取

boolean verifyDeveloperPayload(Purchase p) {
        String payload = p.getDeveloperPayload();
..
}

现在,让我根据代码定义整个场景:

首先,您将发起购买请求,如下所示

String payload = getUserEmailFromAndroidAccounts() + itemUniqueId;

mHelper.launchPurchaseFlow(new PurchaseFinishListener(itemUniqueId), SKU_GAS, 10001,   
   mPurchaseFinishedListener, payload);

如果采购订单成功,Google Play的响应数据将存储在传递回收件人的Purchase对象中。

    private class PurchaseFinishListener implements IabHelper.OnIabPurchaseFinishedListener {
   private final String mItemUniqeId;
    public PurchaseFinishListener(String itemUniqeId) {

            mItemUniqeId = itemUniqeId;
        }

       public void onIabPurchaseFinished(IabResult result, Purchase purchase) 
       {
          if (result.isFailure()) {
             Log.d(TAG, "Error purchasing: " + result);
             return;
          }      
    if (!verifyDeveloperPayLoad(mItemUniqeId , purchase)) {
     Log.d(TAG, "Authenticity verification failed");
             return;
    }

    // set your product as purchased in your DB or server

    }
    }

现在,您的verifyDeveloperPayLoad(购买)方法应如下所示:

 private boolean verifyDeveloperPayLoad(String itemUniqueId , Purchase purchase) {
        String responsePayload = purchase.getDeveloperPayload();
        String computedPayload = getUserEmailFromAndroidAccounts() + itemUniqueId;

        return responsePayload != null && responsePayload.equals(computedPayload);
    }

如果您密切观察代码,您肯定会了解工作流程。

有关基于订阅的购买和一次性购买的更多信息,请访问Android网站。