Redirect_uri_mismatch when contacting Google APIs with OAuth2

Stuart picture Stuart · Apr 11, 2012 · Viewed 14.9k times · Source

I'm creating a mobile app using Sencha Touch and PhoneGap. I want to be able to allow users to log into the app using their Google credentials but am hitting a brick wall with the initial request with the following error:

The redirect URI in the request: http://localhost did not match a registered URI.

My Google API account has the default 2 URIs registered (http://localhost and urn:ietf:wg:oauth:2.0:oob).

I have tried both of these with no success.

The request I am sending contains the following query string params:

The basic process is:

  • build URL as above
  • open new browser window (using ChildBrowser PhoneGap plugin)
  • navigate to the URL
  • at this point the Google login page shows and allows me to put in credentials
  • after Login tap i am taken to an error page containing the above error.

I am testing this in the iPhone simulator and on my iPhone with the same result in both. The application doesn't apear to run on the http://localhost url but on file:///var/mobile/Applications/<guid>/<app name>/www/index.html but there is no option to add this in the Google Console (..or is there? :) )

Does anyone have any suggestions about why this isn't working? I have little to no experience with using OAuth and Google's APIs so any little hints are more than welcome!

Thanks in advance

Stuart

Answer

Antonio Saco picture Antonio Saco · Apr 11, 2012

I suggest you to read this as the best starting point for Google API with OAuth2, and in your case you need this: OAuth2 for Devices.

Probably you are using the wrong endpoint, to request for a user code, you need to use the following endpoint:

https://accounts.google.com/o/oauth2/device/code

This is an example using curl (in your case to authorize the access to the Google+ API):

curl https://accounts.google.com/o/oauth2/device/code -d "client_id=**your_client_id**" -d "scope=https://www.googleapis.com/auth/plus.me" -d "redirect_uri=urn:ietf:wg:oauth:2.0:oob"

You'll get an answer like this:

{
  "device_code" : "4/AToZcyQ7U1BTV-xu4LAqpw02SgIW",
  "user_code" : "bqsj67hb",
  "verification_url" : "http://www.google.com/device",
  "expires_in" : 1800,
  "interval" : 5
}

Then you need to ask for authorization, showning the user the user_code and the verification_url to "pair" your app with the user account of the user. Here there is a good example of this or from the documentation:

After your application has shown the user the user_code and the verification_url, your application may begin polling a Google endpoint with the device_code that was returned with the user_code and verification_url. The URL of the endpoint to poll is https://accounts.google.com/o/oauth2/token, and the interval between requests is specified as the interval in seconds.

The last step, ask for an access_token, using curl:

curl https://accounts.google.com/o/oauth2/token -d "client_id=**your_client_id**&client_secret=**your_client_secret**&code=**the _device_code_obtained_before**&grant_type=http://oauth.net/grant_type/device/1.0" 

you'll get an response like this:

{
  "access_token" : "y23r9.AHES6ZT78qJl14pTueruthfh5676TYDF234-Eme33iQ",
  "token_type" : "Bearer",
  "expires_in" : 3600,
  "id_token" :  "eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXVkIjoiNzgyMTM3OTUzMjkwLmFwcHMuZ29vZ2iLCJ0b2tlbl9oYXNoIjoiUUt0YmxTZUdsRUdNOVdPcUliRGR2QSIsImlhdCI6MTMzNDE3MDI1NywiZXhwIjoxMzM0MTc0MTU3fQ.Iz_Sv9X2fCydj4VfEdDxwWVH70DEK-rSzA5pWV9bvBdYB5VwgwFd8CSnotesDzJxq5pSKGwnAgvBfxSUbuGVmdET3E2sbrLODKymO9FoBzenfVooCwRXurzxvjKWF1EL3007lOPzTx9UGjqwShjjKQRoNjLFs-OmGCJsZGTHTGE",
  "refresh_token" : "1/gjgpKUyppp223s43HMerTX-zS_2JUxQOCk"
}

and finally you can access the services you have granted (don't forget to configure the access from the API console, in your case the Google+ API) with the access_token obtained.

curl https://www.googleapis.com/plus/v1/people/me?access_token=y23r9.AHES6ZT78qJl14pTueruthfh5676TYDF234-Eme33iQ

Regarding the question of

"The application doesn't apear to run on the http://localhost url".

The answer is yes, this is the expected behavior. This redirect_uri is telling you where to callback after successfully granted permissions to your app. In your case a mobile device.

In the case of "urn:ietf:wg:oauth:2.0:oob", is not exactly a redirect. You need to "catch" or "hook" this, to simply continue your process, maybe this can help you or this.

Good luck!