3

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.

Kalina
  • 5,504
  • 16
  • 64
  • 101
  • You answered on your question already in the question :-) http://stackoverflow.com/questions/4543894/android-java-http-post-request find similarities :-) ... But you dont need redirect_uri parameter i think – Selvin Sep 06 '12 at 21:19
  • Could you at least tell me which of the two options I gave it is? It's been three days... Please... – Kalina Sep 07 '12 at 14:05
  • 1
    did you see http://stackoverflow.com/questions/4543894/android-java-http-post-request ... most rated answer ? `List nameValuePairs = new ArrayList(x); nameValuePairs.add(new BasicNameValuePair("code", "4/v6xr77ewYqhvHSyW6UJ1w7jKwAzu")); nameValuePairs.add(new BasicNameValuePair("client_id", "8819981768.apps.googleusercontent.com"));/*...rest of the params...*/ httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));HttpResponse response = httpclient.execute(httppost);` then you should use HttpEntity to translate response to string, then parse json – Selvin Sep 07 '12 at 14:13
  • i co działa? ... to wszystko było w Twoim pytaniu :) – Selvin Sep 07 '12 at 14:20
  • Dalej nie... caly czas dostaje "error: invalid_request" albo "error: invalid_grant" albo "error: invalid_client"... – Kalina Sep 07 '12 at 20:28
  • Use this flow https://developers.google.com/accounts/docs/OAuth2ForDevices and You will need user interaction for the code – Sherif elKhatib Sep 16 '12 at 23:39
  • @Selvin Dopiero teraz dziala! – Kalina Oct 25 '12 at 17:12

2 Answers2

3

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);
Community
  • 1
  • 1
Kalina
  • 5,504
  • 16
  • 64
  • 101
1

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

Community
  • 1
  • 1
Sourab Sharma
  • 2,940
  • 1
  • 25
  • 38