简体   繁体   中英

Getting Invalid Grant on OAuth2 authorization_code post request for Google Play Billing purchase verification

I'm trying to implement purchase verification in my backend as the Google-Play-Billing docs recommend. Following this documentation for subscription purchase verification, it tells me I must make a get request to that URL ( Purchases.subscriptions: get ) with my android app's package name , subscription_id , and purchase token . However, before I can make a get request to that URL, I must authorize my backend server for API requests. So, following the link in that documentation to here , I began following those steps. I created an OAuth 2.0 client ID , then generated the initial refresh token by going to the next url in my browser. My client_id was set to my OAuth 2.0 client ID that was just generated, and my redirect_uri was set to urn:ietf:wg:oauth:2.0:oob , which I received from the JSON file I downloaded from the Google API Console . I successfully retrieved my initial refresh token and put it in my backend code.

Now the goal is to make a successful purchase in my android app, then send a post request to my backend with the necessary parameters. This part works just fine. However, when following the next steps of the authorization documentation , the part where it says to " Exchange this code for an access and refresh token pair by sending a POST request to... " in order to get my access_code , I set the fields to what the docs say to set the fields to, but my request comes back as a 400 error with the error message: " invalid_grant ". I don't understand why I am receiving this error.

Here is my post request code:

List <NameValuePair> parameters = new ArrayList <>();
parameters.add(new BasicNameValuePair("grant_type", "authorization_code"));
parameters.add(new BasicNameValuePair("code", initial_code));
parameters.add(new BasicNameValuePair("client_id", client_id));
parameters.add(new BasicNameValuePair("client_secret", client_secret));
parameters.add(new BasicNameValuePair("redirect_uri", redirect_uri));

RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();
HttpClientBuilder httpClientBuilder = HttpClients.custom().setDefaultRequestConfig(requestConfig);

try (CloseableHttpClient httpClient = httpClientBuilder.build()) {
    HttpPost request = new HttpPost("https://accounts.google.com/o/oauth2/token");
    request.addHeader("content-type", "application/x-www-form-urlencoded");
    request.setEntity(new UrlEncodedFormEntity(parameters));

    try (CloseableHttpResponse response = httpClient.execute(request)) {
        HttpEntity entity = response.getEntity();
        final StatusLine statusLine = response.getStatusLine();
        if (entity != null) {
            System.out.println("Response returned: " + statusLine.getStatusCode() + " - " + EntityUtils.toString(entity));
        }
    }
}

Please help!

Okay, I figured out my problem. I need to be faster about making that first post request to exchange the initial refresh_token for and access_code and new refresh_token. That new refresh_token will end up being my permanent refresh_token for all future api requests. My problem was that the initial refresh_token kept expiring before I made my initial post request. I didn't realize it would expire in 1 hour, and so I kept using the same initial refresh_token without realizing that it was expired.

I followed the rest of the steps on google's docs, and now my backend server is successfully validating my in app subscription purchases.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM