how to get user information in google wallet - android

We want to be able to associate app users with real transactions done.The problem is that we have the user’s email address on application back end side, and we track user purchase amounts, but when we go into the Google Wallet transactions we have no way of knowing which transaction/s belong to that user. We need a solution for this, because even if we have the user's email, we cannot search transactions by email address.
Is it possible to update the receipt numbers we are sending in the API to include the Google Wallet Receipt number instead of the time stamp ?
Please, provide us your suggestions.

I thought the answer would lie in the postback facility. That gives google's user ID and order number. However, I didn't see how to convert either of those to an email address for sending the digital good just purchased.
BTW. I rejected doing the fulfilment client side as that seemed insecure. If I'm wrong about that then why would they offer the postback facility?
... then I realised, we could do part of it client and part server side.
I guessed that something comes back from the client-side success callback.
success: function(result) {
console.log('success',result.response.orderId);
complete(result.response.orderId);
},
So, I now have the google's orderId on the client side and there I know the user's ID. So my complete() function can send the orderId and our userId to the server which can then match this with successful payment orderId from the postback (which happens first) and fulfil the order.
Yes, this is inelegant, but I believe it to be a secure solution.
Maybe slightly more elegant is to use the [sellerData] property in the submission payload to contain our user ID and order ref. We then have more items to match after the success callback has happened. I think I'll hold off delivering the digital good until all those checks have been completed.
What I do not understand is why cannot this kind of suggestion (or a better one) be found in the wallet tutorial?
Paul

My answer here refers to the previous answer provided:
Totally agree on "why cannot this kind of suggestion (or a better one) be found in the wallet tutorial?".
Your suggested solution does not seem to be very secured (to say the least). You want the client to send you their username/email/client-id in the Success callback... This means that anyone will be able to send you their ID, even if they did not make a purchase. They can add a random order-ID and hope to get a match (and then repeat the process many times in order to increase the chances).
My guess is that the username/email/client-id lies somewhere in the request object sent from Google to the postback URL (your server's doPost routine). But I have the feeling that you need to add something in the JWT generated in your Purchase function before it is passed to the google.payments.inapp.buy routine.
Looking for an answer myself...
Here is a possible solution, although I have not yet tested it myself:
Download the 'zip' file from: https://code.google.com/p/wallet-online-quickstart-java/downloads/list
Take the entire 'com' folder and add it to your project source folder (sorry, I have not been able to find a JAR for this package). Then, add the following code to your servlet:
...
import com.google.wallet.online.jwt.JwtResponseContainer;
import com.google.wallet.online.jwt.util.JwtGenerator;
import com.google.wallet.online.jwt.JwtResponse;
...
public void doPost(HttpServletRequest request, HttpServletResponse response) ...
{
try
{
String maskedWalletJwt = request.getParameter("maskedWalletJwt");
JwtResponseContainer jwtResponseContainer = JwtGenerator.jwtToJava(JwtResponseContainer.class, maskedWalletJwt, SellerSecret);
JwtResponse jwtResponse = jwtResponseContainer.getResponse();
String email = jwtResponse.getEmail();
...
}
}
One thing I'm not so sure about, is request.getParameter("maskedWalletJwt").
You might have to add this parameter when calling the google.payments.inapp.buy routine.

Related

What will happen if leave "developer payload" as blank Google Play In-app Billing

Well I have read lots of time about "developer payload" But I am not clearly understand, what for "developer payload" used for. So I am trying to use this as blank like this:
public void onUpgradeAppButtonClicked(String SKU) {
Log.d(TAG,"Upgrade button clicked; launching purchase flow for upgrade.");
/*
* 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.
*/
String payload = "";
mHelper.launchPurchaseFlow(this, SKU, RC_REQUEST,
mPurchaseFinishedListener, payload);
}
And this:
boolean verifyDeveloperPayload(Purchase p) {
String payload = p.getDeveloperPayload();
return true;
}
So I have make a image. for 3 Situations. I want to learn what will happen after condition
Yes the most possible shit occurs at scenario 2.
But how many users are on scenario 2? I think it would be not many. Most people don't share their devices.
But I'm thinking about another crack possibility if this payload string left empty. It would be easy to crack it down.
The only thing makes me mad is this thing should be on Google API side. Google's job to verify and make sure who purchased the item. Why we need our own server?
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.
Think of this as a receipt. If a customer came in and wanted to return an item or warranty, you'd want to be darned sure that receipt wasn't printed at home. Using this token will help prevent fraud.
It's not required, but it is advised. According to the docs you can send an empty string, though I'm not sure about null. It's advisable for security reasons though. You can use the payload to verify that the purchase was made by the user that you intended, for instance. See the billing Security Best Practices

Protecting my Google App Engine API Endpoints

I have been doing a lot of research recently on securing my app engine. Currently, I've been reading through the question below and the links in that question:
How do I restrict Google App Engine Endpoints API access to only my Android applications?
However, it doesn't answer my problem. My question is similar to the question above, restricting access to my endpoint API to only my app. The guy seemed to have got it working when he inputs a correct email into the credentials.
My question is if I can achieve the same results without having to input any credentials. I want it so that only my app can use my endpoint API so to prevent other apps from abusing it and using up my quota. I already got a client id for my android application, and have placed it within my #API annotation. To test if it worked, I made a random value for the client id in the #API notation of another api class. However, my app was still able to use methods from both class. Any help?
-Edit-
From reading from the docs and researching further, the endpoint way of authorizing apps is by authenticating the user and for my API to check if user is null. My question is that in the process of authenticating the user, is Google somehow able to read my app's SHA1 fingerprint and authorize it to its list of client ids? If so, how can I replicate this process in my endpoint so that I check the SHA1 fingerprint of the app making the request and compare it to a set value? I don't understand the mechanics behind the endpoints very well, so correct me if I am understanding this wrong.
If the android app has access, then the user has access. A motivated party has many options for inspecting your protocol, including putting the device behind transparent proxy or simply running the app through a debugger. I do suggest running your app through ProGuard before publishing, as this will make the process [a bit] more difficult.
Ultimately, you'll need to make your appengine API robust against untrusted parties. This is simply the state of the web.
How you can protect your endpoint API is described here: http://android-developers.blogspot.com/2013/01/verifying-back-end-calls-from-android.html
The secret is that you request a token from Google Play using the following scope: audience:server:client_id:9414861317621.apps.googleusercontent.com where 9414861317621.apps.googleusercontent.com is your ClientId.
Google Play will look up the id at your endpoints app and return a Google-signed JSON Web Token if it finds the id. Then you pass that id in with your request. Above article says you should pass it in with the body. I would possibly rather add another parameter for that because otherwise you can't pass your own entities anymore. Anyway, your server backend receives the token, and you ask Google as described if it is authentic, before you process the API request.
If you pass in the token using an extra parameter, you can catch it on the server side by adding HttpServletRequest to your endpoint signature and then using request.getHeader("Yourname") to read it out. Make sure you never add the parameter as a URL parameter as it may be logged somewhere.
public void endpointmethod(
// ... your own parameters here
final HttpServletRequest request
) throws ServiceException, OAuthRequestException {
request.getHeader("YourHeaderName") // read your header here, authenticate it with Google and raise OAuthRequestException if it can't be validated
On the Android side you can pass in your token when you build the endpoint api, like this, so you don't have to do it with each and every request:
Yourapiname.Builder builder = new Yourapiname.Builder(AndroidHttp.newCompatibleTransport(), getJsonFactory(), new HttpRequestInitializer() {
public void initialize(HttpRequest httpRequest) {
httpRequest.setHeader(...);
}})
Hope this helps you make your endpoints API secure. It should.

Android getauthutil getToken not returning a JWT

All,
I am writing an android app and i am trying to use Google+ as my account manager.
I have followed excellent article here and i am prompted to sign into google+ and I event get a token back.
The problem is that the token does not appear to be a JWT ( i know this because there are only 2 dotted parts to the name instead of 3 and that when I pass the "token" to the java referenced in the same article I get an exception suggesting that the all is not well with the token :
com.google.api.client.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:76)
at com.google.api.client.util.Preconditions.checkArgument(Preconditions.java:37)
at com.google.api.client.json.webtoken.JsonWebSignature$Parser.parse(JsonWebSignature.java:473)
at com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.parse(GoogleIdToken.java:57)
at Checker.check(Checker.java:34)
The code looks like this :-
String scope = "oauth2:server:client_id:";
scope += scope_; // my client id in the web section
scope += ":api_scope:";
String googleauth;
googleauth ="https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/plus.login";
scope+=googleauth;
try
{
String token = GoogleAuthUtil.getToken(act_, s_account, scope);
....
The application does ask for verification and I permit it (and call getToken again as you are supposed to).
But the token appears to be unusable, its bound to be something silly, but as yet I cannot see what.
Regards
Not sure what the problem is, but I've read in several places that you need to put some sort of workaround in place to make it work with the Google authentication. You can have a look at http://www.trajano.net/2014/07/parsing-the-json-web-token-in-java/
Hope this helps

What is the proper way to validate google granted OAuth tokens in a node.js server?

I'm trying to authenticate a mobile application for the Android platform to a custom node.js server api. I would like to use Google OAuth2 tokens for this rather than roll my own authentication, since Android devices with Google Play installed make this available to app developers. I'm using the GoogleAuthUtil.getToken call from the Google Play Services library, documented here. I'm trying to follow the advice outlinedin this android developers blogpost
The getToken method is returning in my case a long 857 byte string. If I try to pass this token to Google's TokenInfo endpoint, it returns:
{'error': 'invalid_token', 'error_description': 'Invalid Value'}
What am I doing wrong here? In the 'scope' of the getToken call, I am sending:
audience:server:client_id:**i_put_my_clientid_here**. I have a clientid generated for "installed applications". Using this client id, the call to getToken doesn't work at all. When I generated a client id for a "service account", the call succeeds, but I get an 857 byte token that fails when passed to the TokenInfo endpoint as described above.
EDIT:
I also created a client id for "web applications", as it appears that is the right client id to use when calling getToken. But the behavior is the same, I get back an 857 byte token that doesn't validate when calling Google's endpoint.
How can I properly get a valid auth token using Google Play services on Android? Once I have the right token, what is the right node.js library to validate it server side? Can I use passport-google-oauth ?
Hm, this is really a comment rather than an answer, but I can’t put newlines in those:
it has to be the web-side Clent ID that goes in the put_my_clientid_here spot
if GoogleAuthUtil.getToken() gives you a String withou throwing an Exception, it really ought to be valid. When you hit tokeninfo, did you use ...tokeninfo?id_token=<857-byte-value-here>
if you’re a rubyist, grab the google-id-token gem and see if it can validate your 857-byte token.
If you just want to read the contents of the data returned by GoogleAuthUtil.getToken then the process is very simple. The returned data is simply a JWT. So all you'd have to do is split the data by the . character, and then base64 (url) decode each piece.
It gets slightly more complicated if you want you want to verify the message's authenticity. Simply use your favorite crypto library to do the verification. The 3rd component of the JWT is the signature of the data and the Google certs are publicly available; that's all you need to verify the message.
For a week I have been looking into how to validate GoogleAuthUtil tokens received in Android Client application at Node.js server using passport.js
Finally I came across passport-google-token passport strategy which perfectly performs the task.
https://www.npmjs.com/package/passport-google-token
More details are present in the above link.
The official node SDK lets you do that now.
Here's the link: https://github.com/google/google-auth-library-nodejs/blob/master/lib/auth/oauth2client.js#L384
I'm not too familiar with the details of how Android works with respect to handing a token from the device to the server. My general impression, however, is that you don't go through the typical web-based OAuth dance. Instead, you directly call the "user info" endpoint, which will return the info corresponding to the user who holds the token, or reject the request if the token is invalid. There's some discussion on this related question:
validating Android's authToken on third party server
In effect, the token becomes a secret that is shared between both the device and your server, so its important to protect it.
There are a couple strategies for Facebook and Twitter that were developed to do similar things using tokens from iOS devices:
https://github.com/drudge/passport-twitter-token
https://github.com/drudge/passport-facebook-token
You can take some inspiration from them and tweak it to talk to Google's endpoints. Let me know how this turns out. I'd love to see a similar "passport-google-token" strategy, so if you implement one, let me know and I'll link to it!

Secure in-app purchase for Android

I have followed some tutorials in using in-app purchasing and I got this all to work. But is it possible to use it securely for this example case:
The app is free to download and has some chat functionality. It can
send 100 messages per day. The app can send extra messages for x per
year.
The problem here is: how does the server know the user bought something? Is there a Google service to use and check this? Because by allowing the app to send a message to to server "hey, I just bought this" seems to be wrong.
As part of IAP, you need a BroadcastReceiver to get notifications from Google. One of the notifications is com.android.vending.billing.PURCHASE_STATE_CHANGED. That notification includes a data block and a signature. Transmit both, exactly, to your server. Google Play will supply you with a public key that you can then use to validate the signature of the data block on the server (in php, openssl_verify works). Once you have verified the data on the server, you can then parse the data block (json) to get the list of orders including their product identifiers which tell you what the user has purchased. From there, your own protocols will have to include a device/user/contract identifier to validate against the server. Hard to make recommendations on that part without knowing more about your plans.
on this method you will get the response of transaction.
#Override
public void onRequestPurchaseResponse(RequestPurchase request,
ResponseCode responseCode) {
if responseCode is RESULT_OK means successful transaction.
you can refer this link.
You can relay the information about purchase to your server after receiving from the service.
You can use openssl_verify ($data, $signature, $key)
Data and signature are in your result you get from the service. Key is your public RSA key that you can find in your Developer Console.

Categories

Resources