2
votes

I'm trying to follow this flow to sign-in a user on an android app using a python server backend:

https://developers.google.com/+/web/signin/server-side-flow

I'm successful in getting the authorization code from the Android app, but when I try to exchange this code for an access token from the server, I'm getting an "invalid_request" error.

From the Android app, I'm using the same client_id as the one on the server which is listed under "Client ID for web application" in my console. I've verified the redirect_uri is correct. Is it not possible to generate an authorization code from an Android client and use a server to exchange for the access token?

My python code is:

def auth_params(self):
  client_id, client_secret = self.get_key_and_secret()
  return {
      'grant_type': 'authorization_code',    
      'code': self.data.get('code', ''),  # auth code from app
      'client_id': client_id,
      'client_secret': client_secret,
      'redirect_uri': self.get_redirect_uri()
  }       

@classmethod
def auth_headers(cls):
    return {'Content-Type': 'application/x-www-form-urlencoded',
            'Accept': 'application/json'}

def auth_complete(self, *args, **kwargs):
  params = self.auth_params()
  request = Request('https://accounts.google.com/o/oauth2/token', data=urlencode(params),
                    headers=self.auth_headers())
  try:
      response = simplejson.loads(urlopen(request).read())
  except HTTPError, e:
      print 'fml'
1

1 Answers

3
votes

There are two special redirect URIs that do not actually redirect back to the server: "postmessage" and "urn:ietf:wg:oauth:2.0:oob". These special redirect URIs do not trigger a redirect POST to your server but instead return the OAuth 2.0 tokens in a response to the request.

When you exchange the code for an access token and refresh token, the redirect URI associated with the authorization code needs to match.

Because your authorization code is coming from an Android device, your redirect URI is probably mismatched on this line:

  'redirect_uri': self.get_redirect_uri()

For Android code exchange, the redirect URI must be: urn:ietf:wg:oauth:2.0:oob

Hopefully that helps. As you may have noticed, if you are also taking an authorization code returned from a Web sign-in or Android, you will need to set the redirect URI appropriately (e.g. urn[...] for Android, 'postmessage' or the configured redirect otherwise).