Making an HTTP post request to the Google Play And

2019-07-06 05:26发布

问题:

I'm trying to authorize the Google Play Android Developer API. I'm at the step where I need to make an HTTP post request to exchange the authorization code for an access token and a refresh token. Google gives the following example request:

POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded

code=4/v6xr77ewYqhvHSyW6UJ1w7jKwAzu&
client_id=8819981768.apps.googleusercontent.com&
client_secret={client_secret}&
redirect_uri=https://oauth2-login-demo.appspot.com/code&
grant_type=authorization_code

I'm confused... First of all, for an installed application (Android) no client_secret is given. I created a web application for the same project in the Google API Console and this gave me a client_secret, so I used that, even though there is no web application. The following code gives me an "invalid_grant" error:

HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("https://accounts.google.com/o/oauth2/token");

try {
    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(5);
    nameValuePairs.add(new BasicNameValuePair("code", "CODE"));
    nameValuePairs.add(new BasicNameValuePair("client_id", "CLIENT_ID"));
    nameValuePairs.add(new BasicNameValuePair("client_secret", "CLIENT_SECRET"));
    nameValuePairs.add(new BasicNameValuePair("redirect_uri", "urn:ietf:wg:oauth:2.0:oob"));
    nameValuePairs.add(new BasicNameValuePair("grant_type", "authorization_code"));
    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

    HttpResponse response = httpclient.execute(httppost);
    ....

Taking out the client_secret entirely gave me an "invalid_request" error.

回答1:

This is how I solved it. I ended up using a Web Applcation. See more details in my response here.

HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/token");

List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(4);
nameValuePairs.add(new BasicNameValuePair("grant_type",    "refresh_token"));
nameValuePairs.add(new BasicNameValuePair("client_id",      CLIENT_ID));
nameValuePairs.add(new BasicNameValuePair("client_secret",  CLIENT_SECRET));
nameValuePairs.add(new BasicNameValuePair("refresh_token",  REFRESH_TOKEN));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));

HttpResponse response = client.execute(post);


回答2:

I have managed to redeem access code for access token from android app without the help of web application by simply eliminating the client_secret key as it is not applicable for installed applications.

HttpPost httppost = new HttpPost("https://accounts.google.com/o/oauth2/token");
httppost.setHeader("Content-type", "application/x-www-form-urlencoded");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(4);
nameValuePairs.add(new BasicNameValuePair("grant_type",    "authorization_code"));
nameValuePairs.add(new BasicNameValuePair("client_id",      BLOGGER_CLIENT_ID));
nameValuePairs.add(new BasicNameValuePair("redirect_uri",  "http://localhost"));
nameValuePairs.add(new BasicNameValuePair("code", BLOGGER_ACCESS_CODE));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpClient httpClient = new DefaultHttpClient(myParams);
response = httpClient.execute(httppost);
String returnedJsonStr = EntityUtils.toString(response.getEntity());
JSONObject jsonObject = new JSONObject(returnedJsonStr);
String receivedToken = jsonObject.getString("access_token");

Reason to post this comment is that your solution can be misleading to someone who might think only way to get access token in mobile apps is via web-application, which I thought after reading your post few minutes ago !

To avoid invalid_grant error follow this code: https://stackoverflow.com/a/14141020/989418