RickyShin / marketbilling

Automatically exported from code.google.com/p/marketbilling
0 stars 0 forks source link

IInAppBillingService doesn't have a method to retrieve Google ID #129

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
In order to generate and verify the developerPayload for the purchase flow the 
Trivial Drive app recommends:

"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)."

The documentation recommends:

"You should pass in a string token that helps your application to identify the 
user who made the purchase, so that you can later verify that this is a 
legitimate purchase by that user. For consumable items, you can use a randomly 
generated string, but for non-consumable items you should use a string that 
uniquely identifies the user."

The problem with this is a user may have multiple Google accounts on their 
device.  We have no way of knowing which Google account was used to 
download/buy the app and thus which Google account was used to buy the in-app 
product.  The BillingService should have an API to retrieve the user id or a 
hash of the user id used for completing the purchase so we can have a complete 
and secure purchase flow.  As it is now the developer payload is useless for 
cross-device scenarios where multiple accounts are involved.

I've noticed that internally the Billing Service has access to this data.  
There are logs:

07-09 10:52:21.973: D/Finsky(7061): [360] 
InAppBillingUtils.getPreferredAccount: com.test.app: Account from first account 
- [oUL818ubKH0PsIrmUFng-SsKDyc]

This even looks like a user id hash.  I would LOVE if that info could be piped 
through an api or attached to the getSkuDetails(), getPurchases(), or 
getBuyIntent() apis.

Numerous others have run into this issue as well: 

http://stackoverflow.com/questions/15192184/what-to-use-as-the-developer-payload
-in-google-in-app-billing-apis
http://stackoverflow.com/questions/14553515/why-is-it-important-to-set-the-devel
oper-payload-with-in-app-billing

Ideally we'd have access to the full user id (even if it requires a 
GET_ACCOUNTS permission).  We have a server that does our receipt verification 
and could do our payload verification.  We would love to entitle users to the 
same content they bought on Android in the browser or on other devices if they 
log in with the same Google ID.  Is the hash that InAppBillingUtils uses 
reproducible on our side so we can match up which real ID was used?   

If this can't be exposed in a timely manner is there any workaround you can 
suggest?  I suppose we could:

* use the AccountManager or ContactsContract.Profile api and ask for the 
GET_ACCOUNTS or READ_PROFILE and READ_CONTACTS permissions
* When making a purchase specify a developerPayload of a comma-separated list 
of all the Google IDs on the device
* When verifying a purchase check that one of the currently logged in Google 
ids is one of the comma-separated ids in the payload

This would have the disadvantage, though, of entitling more accounts to the 
content than bought it (all 4 accounts logged into a device get entitled to 
something even if only one account purchased it).

Your thoughts, explanations, or suggestions would be greatly appreciated.

Thanks,

Matt

API VERSION: v3
OS VERSION:  4.2.2
MARKET/MYAPPS VERSION:  4.1.6
DEVICE:  Nexus 7

Original issue reported on code.google.com by mtt.mllns@gmail.com on 9 Jul 2013 at 8:27

GoogleCodeExporter commented 9 years ago
developer payload seems to be totally useless unless you have an app that has 
its own user identification mechanism (login/password) and you don't want 
purchased items bought with Google user X transmit to your app logged users A, 
B, C through Google user X.

Instead of using developer payload (or obfuscating IAB code that will be easily 
craked no matter what), it is a lot more useful to add many hard to find online 
CRC check in the code.

Original comment by pujos.mi...@gmail.com on 18 Aug 2013 at 9:38

GoogleCodeExporter commented 9 years ago
We shouldn't need to request extra permissions such as (GET_ACCOUNTS) in order 
to get a hash of the buyer's current user id. Also, as Matt has indicated, we 
would also need an array of hashes of the userid's currently on the device, to 
validate a purchase if any of the user accounts on the device is present in the 
developer payload. 

The argument that, since there is no perfect security, there's no point in 
providing moderate security is unreasonable. As an analogy, a locked door 
really is not secure, since you can always break windows. So, by this 
rationale, none of us should lock our doors, since it is not really secure 
anyways. Most of us prefer to live in the real world, where locking doors 
actually does act as a deterrent to most people. 

I think, in general, we developers are not looking for perfect security against 
hackers. We're looking to make our apps more secure to guard against the vast 
majority of hackers, who are probably idiots that just use existing hacking 
tools with little understanding of how they work.

Original comment by ginolee...@gmail.com on 11 Jul 2014 at 1:25