Recently, I found myself wrestling with the OAuth implementations of several social sites. Now that I have completed integrating OAuth services from Twitter, LinkedIn, and Google it has made my app much better for the end user. However, I had a fair amount of difficulty integrating them all, as each provider implemented the handshake differently. So in the event that someone else is doing this I decided to write my first set of tutorials (three total) on what I did.
The most difficult to figure out, by far, was Google’s OAuth 1.0 implementation, and is the subject of this post. The root of these difficulties was the one off’s that I ran into for different services and libraries in Google’s APIs. The examples provided by Google did not seem match the Contact API that I was using. I finished this code before Google released OAuth 2.0.
The first step to doing anything OAuth with Google APIs is to register your domain at https://www.google.com/accounts/ManageDomains.
After registering your domain you can grab your OAuth Consumer Key and Secret, which are used for the OAuth handshake with Google. You can also upload a certificate, but we are not going to do that here
Django OAuth Handshake
There are several steps to OAuth Handshake:
- Set OAuth input parameters
- Fetch OAuth Request token
- Set the fetched OAuth token
- Generate OAuth authorization URL
- Upgrade to an OAuth access token
Before we get to the coding here are all of the requisite libraries and settings that the code uses. All of the libraries other than gdata can be installed using pip.
- gdata==2.0.13 (http://code.google.com/p/gdata-python-client/downloads/detail?name=gdata-2.0.13.zip)
Variables in settings.py
# used by google to call your app after the user grants access GOOGLE_CALLBACK_URL = u'http://localhost:8080/google_oauth_verifier' # used during the handshake process GOOGLE_CONSUMER_KEY = u'<< your domain >>' GOOGLE_CONSUMER_SECRET = u'<< your secret >>'
For completeness, I also had this in the urls.py
# your app calls this one (r'^google_oauth/$', '<< your app >>.views.google_oauth'), # (r'^google_oauth_verifier', '<< your app >>.views.google_oauth_verifier'),
The following code references the handshake steps I mentioned earlier.
@login_required def google_oauth(request): """Google oauth stuff getting google contacts""" gd_client = gdata.contacts.service.ContactsService() #STEP 1: Set OAuth input parameters. gd_client.SetOAuthInputParameters( gdata.auth.OAuthSignatureMethod.HMAC_SHA1, settings.GOOGLE_CONSUMER_KEY, consumer_secret=settings.GOOGLE_CONSUMER_SECRET) #STEP 2: Fetch OAuth Request token. request_token = gd_client.FetchOAuthRequestToken() #STEP 3: Set the fetched OAuth token. gd_client.SetOAuthToken(request_token) request.session['gd_client'] = gd_client #STEP 4: Generate OAuth authorization URL. auth_url = gd_client.GenerateOAuthAuthorizationURL( callback_url=settings.GOOGLE_CALLBACK_URL) return HttpResponseRedirect(auth_url) @login_required def google_oauth_verifier(request): """google_oauth_verifier this is what gets called by the google callback""" gd_client = request.session['gd_client'] #STEP 5: Upgrade to an OAuth access token gd_client.UpgradeToOAuthAccessToken() request.session['gd_client'] = gd_client return HttpResponseRedirect('/yourapp/somewhere')
This is the code that should correspond to your ‘/yourapp/somewhere/’ url, it is what checks for the gd_client and fires off the OAuth handshake if needed.
if not request.session.__contains__('gd_client'): return HttpResponseRedirect(Site.objects.get_current().domain + '/accounts/google_oauth') gd_client = request.session['gd_client']
That should about do it. I hope this helps anyone that is attempting to do this, if you found it helpful or have any questions just leave a comment. This was my first tutorial so it may not be exactly crystal clear ;P.