Register with Oauth – Microsoft (Live)

For this last post in the series on oauth we’ll take a look at Microsoft (aka Hotmail, aka Live). But before we begin, read the overview / disclaimer. Now for Microsft …

First off, ensure that you have registered your application with Microsoft and have created the following in your settings file:

# https://manage.dev.live.com/Applications/Index
MICROSOFT_CLIENT_ID = 'YOUR-APP-ID'
MICROSOFT_CLIENT_SECRET = 'YOUR-APP-SECRET'

view raw
settings.py
hosted with ❤ by GitHub

1) Create the redirect URL

The first step in the oauth handshake is to redirect to Microsoft with some application specific data in the URL including your client ID, scope (what data you want access to) and redirect URL (where you want Microsoft to send the user after they’ve approved / denied the application)

import urllib
from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.context_processors import csrf
def get_authorization_url(request):
# encode the url
redirect_url = urllib.quote_plus(settings.SITE_URL + reverse('register_microsoft'))
# create a unique state value for CSRF validation
request.session['microsoft_state'] = unicode(csrf(request)['csrf_token'])
# redirect to microsoft for approval
url = 'https://login.live.com/oauth20_authorize.srf?' \
+ 'client_id=' + settings.MICROSOFT_CLIENT_ID \
+ '&redirect_uri=' + redirect_url \
+ '&scope=wl.signin%20wl.basic%20wl.emails' \
+ '&state=' + request.session['microsoft_state'] \
+ '&response_type=code'
return url

view raw
microsoft.py
hosted with ❤ by GitHub

2) Redirect to provider’s site

This url can now be used to redirect to Microsoft (i.e. HttpResponseRedirect(url)):

3) Handle the response (approved or denied)

Once the user makes their choice to approve or deny, Microsoft will redirect back to your redirect_url. You will need to verify the user approved the application:

def verify(request):
# ensure we have a session state and the state value is the same as what microsoft returned
if 'microsoft_state' not in request.session \
or 'state' not in request.GET \
or 'code' not in request.GET \
or request.session['microsoft_state'] != request.GET['state']:
return False
else:
return True

view raw
microsoft.py
hosted with ❤ by GitHub

If any of the above tests fail, we can safely assume the user either arrived at this page directly (i.e. by typing in the URL) or they denied the application. Either way we don’t want to proceed and should redirect them to the start of the registration flow (i.e. HttpResponseRedirect(reverse('register'))).

4 & 5) Get an access token and the user’s profile

At this point the user has authorized your application but you don’t have actual access to their data yet. To get that you’ll need to request an access token. Notice that we’re saving the access token to the user’s session as we don’t want to request it more than once during the registration flow.

Once you have the access token, you can then make the request for the user’s profile data:

import urllib2
import json
import re
from django.conf import settings
from django.core.urlresolvers import reverse
def get_user_data(request, redirect_url):
data = {}
# if we don't have a token yet, get one now
if 'microsoft_access_token' not in request.session:
# set the token URL
url = 'https://login.live.com/oauth20_token.srf'
# set the post params
params = {
'code': request.GET['code'],
'client_id': settings.MICROSOFT_CLIENT_ID,
'client_secret': settings.MICROSOFT_CLIENT_SECRET,
'redirect_uri': redirect_url,
'grant_type': 'authorization_code'
}
# grab the token from microsoft
response = urllib2.urlopen(url, urllib.urlencode(params)).read()
# parse the response
tokens = json.loads(response)
# save the token
request.session['microsoft_access_token'] = tokens['access_token']
# set the url using the user id
url = 'https://apis.live.net/v5.0/me?access_token=' + request.session['microsoft_access_token']
# get the user's data from microsoft
response = urllib2.urlopen(url).read()
user = json.loads(response)
# get the user's info
data['user_id'] = user['id']
data['username'] = re.sub('[^0-9a-zA-Z]+', '', user['name']).lower() if user['name'] is not None else ''
data['email'] = user['emails']['account'] if 'account' in user['emails'] else ''
data['full_name'] = user['name']
data['first_name'] = user['first_name']
data['last_name'] = user['last_name']
data['timezone'] = None
# Microsoft doesn't appear to return the profile picture even if one is set, so use their default image instead
data['picture'] = 'https://secure.wlxrs.com/$live.controls.images/ic/bluemanmxxl.png'
# clean up the name
data['first_name'] = Formatting.clean_name(data['first_name'])
data['last_name'] = Formatting.clean_name(data['last_name'])
return data

view raw
microsoft.py
hosted with ❤ by GitHub

That’s it! You can now use the user’s profile information to pre-fill a registration form, perhaps skipping over fields where you already have a required value such as an email address or first and last name. Just be sure to save their Microsoft ID along with their profile so you can use it validate them in the future. You should also save the access_token and expires values so that you can make future requests to the API for this user or refresh the access token when it has expired.

In a future post I’ll be looking at how to detect an already registered user as well as provide a login with this provider button.

Django Register with Oauth – Yahoo!

Continuing the oauth series but before we begin, read the overview / disclaimer. On to Yahoo!…

For this tutorial you will need Oauth2 installed.

First off, ensure that you have registered your application with Yahoo! and have created the following in your settings file:

# https://developer.apps.yahoo.com/projects
YAHOO_CONSUMER_KEY = 'YOUR-APP-ID'
YAHOO_CONSUMER_SECRET = 'YOUR-APP-SECRET'

view raw
settings.py
hosted with ❤ by GitHub

1) Create the redirect URL

Yahoo is a little bit more complicated than the previous providers in that the first step requires you to get a request token before redirecting to Yahoo!. Much like the other examples, this also requires a redirect URL and the consumer key, but we also have some new data that’s required including a timestamp, nonce (any unique string), version and language.

Once you’ve got the request token, you can use it to create the authorization URL.

import urllib2
import urlparse
import time
import oauth2 as oauth
from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.context_processors import csrf
def get_authorization_url(request):
# URL to where we will redirect to
redirect_url = settings.SITE_URL + reverse('register_yahoo')
# set the api URL
url = 'https://api.login.yahoo.com/oauth/v2/get_request_token'
# required params for yahoo
params = {
'oauth_callback': redirect_url,
'oauth_timestamp': str(int(time.time())),
'oauth_nonce': unicode(csrf(request)['csrf_token']),
'oauth_version': '1.0',
'xoauth_lang_pref': 'en-us'
}
# create the consumer
consumer = oauth.Consumer(key=settings.YAHOO_CONSUMER_KEY, secret=settings.YAHOO_CONSUMER_SECRET)
# create the request
req = oauth.Request(method='GET', url=url, parameters=params)
# sign the request
signature_method = oauth.SignatureMethod_PLAINTEXT()
req.sign_request(signature_method, consumer, None)
# get the request token from yahoo
response = urllib2.urlopen(req.to_url()).read()
# parse the response
params = urlparse.parse_qs(response)
# store the returned values
request.session['yahoo_oauth_token'] = params['oauth_token'][0]
request.session['yahoo_oauth_token_secret'] = params['oauth_token_secret'][0]
# get the authorization URL
url = 'https://api.login.yahoo.com/oauth/v2/request_auth?oauth_token=' + params['oauth_token'][0]
return url

view raw
yahoo.py
hosted with ❤ by GitHub

2) Redirect to provider’s site

This url can now be used to redirect to Yahoo! (i.e. HttpResponseRedirect(url)):

3) Handle the response (approved or denied)

Once the user makes their choice to approve or deny, Yahoo! will redirect back to your redirect_url. You will need to verify the user approved the application:

def verify(request):
# ensure we have a session token and the token value is the same as what yahoo returned
if 'yahoo_oauth_token' not in request.session \
or 'oauth_token' not in request.GET \
or 'oauth_verifier' not in request.GET \
or request.session['yahoo_oauth_token'] != request.GET['oauth_token']:
return False
else:
return True

view raw
yahoo.py
hosted with ❤ by GitHub

If any of the above tests fail, we can safely assume the user either arrived at this page directly (i.e. by typing in the URL) or they denied the application. Either way we don’t want to proceed and should redirect them to the start of the registration flow (i.e. HttpResponseRedirect(reverse('register'))).

4 & 5) Get an access token and the user’s profile

At this point the user has authorized your application but you don’t have actual access to their data yet. To get that you’ll need to request an access token. Notice that we’re saving the access token to the user’s session as we don’t want to request it more than once during the registration flow.

Once you have the access token, you can then make the request for the user’s profile data:

import urllib2
import urlparse
import time
import json
import re
import oauth2 as oauth
from django.conf import settings
def get_user_data(request):
data = {}
# if we don't have a token yet, get one now
if 'yahoo_access_token' not in request.session:
# set the api URL
url = 'https://api.login.yahoo.com/oauth/v2/get_token'
# required params for yahoo
params = {
'oauth_timestamp': str(int(time.time())),
'oauth_nonce': unicode(csrf(request)['csrf_token']),
'oauth_version': '1.0',
'xoauth_lang_pref': 'en-us',
'oauth_verifier': request.GET['oauth_verifier']
}
# create the consumer and token
consumer = oauth.Consumer(key=settings.YAHOO_CONSUMER_KEY, secret=settings.YAHOO_CONSUMER_SECRET)
token = oauth.Token(key=request.session['yahoo_oauth_token'], secret=request.session['yahoo_oauth_token_secret'])
# create the request
req = oauth.Request(method='GET', url=url, parameters=params)
# sign the request
signature_method = oauth.SignatureMethod_PLAINTEXT()
req.sign_request(signature_method, consumer, token)
# get the request token from yahoo
response = urllib2.urlopen(req.to_url()).read()
# parse the response
params = urlparse.parse_qs(response)
# store the returned values
request.session['yahoo_guid'] = params['xoauth_yahoo_guid'][0]
request.session['yahoo_access_token'] = params['oauth_token'][0]
request.session['yahoo_access_token_secret'] = params['oauth_token_secret'][0]
# set the url using the user id
url = 'http://social.yahooapis.com/v1/user/%s/profile?format=json' % request.session['yahoo_guid']
consumer = oauth.Consumer(key=settings.YAHOO_CONSUMER_KEY, secret=settings.YAHOO_CONSUMER_SECRET)
token = oauth.Token(key=request.session['yahoo_access_token'], secret=request.session['yahoo_access_token_secret'])
# get the user's data from yahoo
client = oauth.Client(consumer, token)
response, content = client.request(url)
# grab the profile from the response
user = json.loads(content)['profile']
# split the name
full_name = user['nickname'].split(' ', 1)
# get the user's info
data['user_id'] = user['guid']
data['username'] = re.sub('[^0-9a-zA-Z]+', '', user['nickname']).lower()
data['email'] = user['emails'][0]['handle'] if 'handle' in user['emails'][0] else ''
data['full_name'] = user['nickname']
data['first_name'] = full_name[0] if len(full_name) > 0 else ''
data['last_name'] = full_name[1] if len(full_name) >= 2 else ''
data['timezone'] = user['timeZone']
data['picture'] = user['image']['imageUrl']
return data

view raw
yahoo.py
hosted with ❤ by GitHub

That’s it! You can now use the user’s profile information to pre-fill a registration form, perhaps skipping over fields where you already have a required value such as an email address or first and last name. Just be sure to save their Yahoo! ID along with their profile so you can use it validate them in the future. You should also save the access_token and expires values so that you can make future requests to the API for this user or refresh the access token when it has expired.

In a future post I’ll be looking at how to detect an already registered user as well as provide a login with this provider button.

Django Register with Oauth – Google

Before we begin, read the overview / disclaimer. Now for Google…

First off, ensure that you have registered your application with Google and have created the following in your settings file:

# https://code.google.com/apis/console/
GOOGLE_OAUTH2_CLIENT_ID = 'YOUR-APP-ID'
GOOGLE_OAUTH2_CLIENT_SECRET = 'YOUR-APP-SECRET'

view raw
settings.py
hosted with ❤ by GitHub

1) Create the redirect URL

The first step in the oauth handshake is to redirect to Google with some application specific data in the URL including your client ID, scope (what data you want access to) and redirect URL (where you want Google to send the user after they’ve approved / denied the application)

import urllib
from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.context_processors import csrf
def get_authorization_url(request):
# URL to where we will redirect to
redirect_url = urllib.quote_plus(settings.SITE_URL + reverse('register_google'))
# create a unique state value for CSRF validation
request.session['google_state'] = unicode(csrf(request)['csrf_token'])
scope = urllib.quote_plus('https://www.googleapis.com/auth/userinfo.email') + '+' + \
urllib.quote_plus('https://www.googleapis.com/auth/userinfo.profile')
# redirect to google for approval
url = 'https://accounts.google.com/o/oauth2/auth?' \
+ 'scope=' + scope \
+ '&state=' + request.session['google_state'] \
+ '&redirect_uri=' + redirect_url \
+ '&response_type=code' \
+ '&client_id=' + settings.GOOGLE_OAUTH2_CLIENT_ID \
+ '&access_type=offline' \
+ '&approval_prompt=auto'
return url

view raw
google.py
hosted with ❤ by GitHub

2) Redirect to provider’s site

This url can now be used to redirect to Google (i.e. HttpResponseRedirect(url)):

3) Handle the response (approved or denied)

Once the user makes their choice to approve or deny, Google will redirect back to your redirect_url. You will need to verify the user approved the application:

def verify(request):
# Google will direct with state and code in the URL
# ?state=zNHRjuYO…&code=4/zK5F93g2we…
# ensure we have a session state and the state value is the same as what google returned
if 'google_state' not in request.session \
or 'state' not in request.GET \
or 'code' not in request.GET \
or request.session['google_state'] != request.GET['state']:
return False
else:
return True

view raw
google.py
hosted with ❤ by GitHub

If any of the above tests fail, we can safely assume the user either arrived at this page directly (i.e. by typing in the URL) or they denied the application. Either way we don’t want to proceed and should redirect them to the start of the registration flow (i.e. HttpResponseRedirect(reverse('register'))).

4 & 5) Get an access token and the user’s profile

At this point the user has authorized your application but you don’t have actual access to their data yet. To get that you’ll need to request an access token. Notice that we’re saving the access token to the user’s session as we don’t want to request it more than once during the registration flow.

Once you have the access token, you can then make the request for the user’s profile data:

import urllib2
import json
import re
from django.conf import settings
from django.core.urlresolvers import reverse
def get_user_data(request):
data = {}
# if we don't have a token yet, get one now
if 'google_access_token' not in request.session:
# URL to where we will redirect to
redirect_url = settings.SITE_URL + reverse('register_google')
# set the token URL
token_url = 'https://accounts.google.com/o/oauth2/token'
# set the post params
params = {
'code': request.GET['code'],
'client_id': settings.GOOGLE_OAUTH2_CLIENT_ID,
'client_secret': settings.GOOGLE_OAUTH2_CLIENT_SECRET,
'redirect_uri': redirect_url,
'grant_type': 'authorization_code'
}
# grab the token from google
response = urllib2.urlopen(token_url, urllib.urlencode(params)).read()
# parse the response
tokens = json.loads(response)
# save the token
request.session['google_access_token'] = tokens['access_token']
request.session['google_access_token_expires'] = token['expires_in']
# set the api URL using the token we just fetched
api_url = 'https://www.googleapis.com/oauth2/v1/userinfo?' \
+ 'access_token=' + request.session['google_access_token']
# get the user's data from google
response = urllib2.urlopen(api_url).read()
user = json.loads(response)
# get the user's info
data['user_id'] = user['id']
data['username'] = re.sub('[^0-9a-zA-Z]+', '', user['email'].split('@')[0]).lower()
data['email'] = user['email']
data['full_name'] = user['name']
data['first_name'] = user['given_name']
data['last_name'] = user['family_name']
data['timezone'] = user['timezone'] if 'timezone' in user else None
data['picture'] = user['picture'] if 'picture' in user else \
'https://lh4.googleusercontent.com/-yMO06Y5jMmA/AAAAAAAAAAI/AAAAAAAAAAA/mV7mqn9o52w/s250-c-k/photo.jpg'
return data

view raw
google.py
hosted with ❤ by GitHub

That’s it! You can now use the user’s profile information to pre-fill a registration form, perhaps skipping over fields where you already have a required value such as an email address or first and last name. Just be sure to save their Google ID along with their profile so you can use it validate them in the future. You should also save the access_token and expires values so that you can make future requests to the API for this user or refresh the access token when it has expired.

In a future post I’ll be looking at how to detect an already registered user as well as provide a login with this provider button.

Django Register with Oauth – Twitter

Before we begin, read the overview / disclaimer. Now for Twitter…

For this tutorial you’ll need to install Tweepy.

First off, ensure that you have registered your application with Twitter and have created the following in your settings file:

# https://dev.twitter.com/apps
TWITTER_CONSUMER_KEY = 'YOUR-APP-ID'
TWITTER_CONSUMER_SECRET = 'YOUR-APP-SECRET'

view raw
settings.py
hosted with ❤ by GitHub

1) Create the redirect URL

The first step in the oauth handshake is to redirect to Twitter with the oauth token (generated when the request token is fetched below):

import tweepy
from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.context_processors import csrf
def get_authorization_url(request):
# URL to where we will redirect to
redirect_url = settings.SITE_URL + reverse('register_twitter')
# create the handler
auth = tweepy.OAuthHandler(settings.TWITTER_CONSUMER_KEY, settings.TWITTER_CONSUMER_SECRET, redirect_url)
# get the authorization url (i.e. https://api.twitter.com/oauth/authorize?oauth_token=XXXXXXX)
# this method automatically grabs the request token first
# Note: must ensure a callback URL (can be any URL) is defined for the application at dev.twitter.com,
# otherwise this will fail (401 Unauthorized)
try:
url = auth.get_authorization_url()
except tweepy.TweepError:
# failed to get auth url (maybe twitter is down)
url = reverse('home')
return url
# store the returned values
request.session['twitter_request_token_key'] = auth.request_token.key
request.session['twitter_request_token_secret'] = auth.request_token.secret
return url

view raw
twitter.py
hosted with ❤ by GitHub

2) Redirect to provider’s site

This url can now be used to redirect to Twitter (i.e. HttpResponseRedirect(url)):

3) Handle the response (approved or denied)

Once the user makes their choice to approve or deny, Twitter will redirect back to your redirect_url. You will need to verify the user approved the application:

def verify(request):
# Twitter will direct with oauth_token and oauth_verifier in the URL
# ?oauth_token=EoSsg1…&oauth_verifier=NB3bvAkb…
# did the user deny the request
if 'denied' in request.GET:
return False
# ensure we have a session state and the state value is the same as what twitter returned
if 'twitter_request_token_key' not in request.session \
or 'oauth_token' not in request.GET \
or 'oauth_verifier' not in request.GET \
or request.session['twitter_request_token_key'] != request.GET['oauth_token']:
return False
else:
return True

view raw
twitter.py
hosted with ❤ by GitHub

If any of the above tests fail, we can safely assume the user either arrived at this page directly (i.e. by typing in the URL) or they denied the application. Either way we don’t want to proceed and should redirect them to the start of the registration flow (i.e. HttpResponseRedirect(reverse('register'))).

4 & 5) Get an access token and the user’s profile

At this point the user has authorized your application but you don’t have actual access to their data yet. To get that you’ll need to request an access token. Notice that we’re saving the access token to the user’s session as we don’t want to request it more than once during the registration flow.

Once you have the access token, you can then make the request for the user’s profile data:

import json
import tweepy
from django.conf import settings
from app.lib import RawJsonParser
def get_user_data(request):
data = {}
# create the connection
auth = tweepy.OAuthHandler(settings.TWITTER_CONSUMER_KEY, settings.TWITTER_CONSUMER_SECRET)
# set the token and verifier
auth.set_request_token(request.GET['oauth_token'], request.GET['oauth_verifier'])
# determine if we've already requested an access token
if 'twitter_access_token_key' not in request.session:
# get the access token
access_token = auth.get_access_token(request.GET['oauth_verifier'])
# update the stored values
request.session['twitter_access_token_key'] = access_token.key
request.session['twitter_access_token_secret'] = access_token.secret
else:
# set the access token
auth.set_access_token(request.session['twitter_access_token_key'], request.session['twitter_access_token_secret'])
# create the API instance
api = tweepy.API(auth_handler=auth, parser=RawJsonParser())
user = json.loads(api.me())
# split the name
full_name = user['name'].split(' ', 1)
# get the user's info
data['user_id'] = user['id']
data['username'] = user['screen_name']
data['full_name'] = user['name']
data['first_name'] = full_name[0] if len(full_name) > 0 else ''
data['last_name'] = full_name[1] if len(full_name) >= 2 else ''
data['timezone'] = 0 if user['utc_offset'] is None else user['utc_offset'] / 3600
data['picture'] = user['profile_image_url'].replace('_normal', '')
return data

view raw
twitter.py
hosted with ❤ by GitHub

One thing to notice is that a custom parser is being used to get the raw json data coming from Twitter. Here’s what that parser looks like:

from tweepy.parsers import Parser
class RawJsonParser(Parser):
def parse(self, method, payload):
return payload

view raw
lib.py
hosted with ❤ by GitHub

That’s it! You can now use the user’s profile information to pre-fill a registration form, perhaps skipping over fields where you already have a required value such as an email address or first and last name. Just be sure to save their Twitter ID along with their profile so you can use it validate them in the future. You should also save the access token key and secret so that you can make future requests to the API for this user. Note that Twitter does not currently expire access tokens like other providers.

In a future post I’ll be looking at how to detect an already registered user as well as provide a login with this provider button.

Django Register with Oauth – Facebook

Now that you’ve read the overview / disclaimer, let’s dive into Facebook.

First off, ensure that you have registered your application with Facebook and have created the following in your settings file:

# https://developers.facebook.com/apps
FACEBOOK_APP_ID = 'YOUR-APP-ID'
FACEBOOK_API_SECRET = 'YOUR-APP-SECRET'

view raw
settings.py
hosted with ❤ by GitHub

1) Create the redirect URL

The first step in the oauth handshake is to redirect to Facebook with some application specific data in the URL including your application ID and redirect URL (where you want Facebook to send the user after they’ve approved / denied the application):

import urllib
from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.context_processors import csrf
def get_authorization_url(request):
# URL to where Facebook will redirect to
redirect_url = urllib.quote_plus(settings.SITE_URL + reverse('register_facebook'))
# create a unique state value for CSRF validation
request.session['facebook_state'] = unicode(csrf(request)['csrf_token'])
# redirect to facebook for approval
url = 'https://www.facebook.com/dialog/oauth?' \
+ 'client_id=' + settings.FACEBOOK_APP_ID \
+ '&redirect_uri=' + redirect_url \
+ '&scope=email' \
+ '&state=' + request.session['facebook_state']
return url

view raw
facebook.py
hosted with ❤ by GitHub

2) Redirect to provider’s site

This url can now be used to redirect to Facebook (i.e. HttpResponseRedirect(url)):

3) Handle the response (approved or denied)

Once the user makes their choice to approve or deny, Facebook will redirect back to your redirect_url. You will need to verify the user approved the application:

def verify(request):
# Facebook will direct with state and code in the URL
# ?state=ebK3Np…&code=AQDJEtIZEDU…#_=_
# ensure we have a session state and the state value is the same as what facebook returned
# also ensure we have a code from facebook (not present if the user denied the application)
if 'facebook_state' not in request.session \
or 'state' not in request.GET \
or 'code' not in request.GET \
or request.session['facebook_state'] != request.GET['state']:
return False
else:
return True

view raw
facebook.py
hosted with ❤ by GitHub

If any of the above tests fail, we can safely assume the user either arrived at this page directly (i.e. by typing in the URL) or they denied the application. Either way we don’t want to proceed and should redirect them to the start of the registration flow (i.e. HttpResponseRedirect(reverse('register'))).

4 & 5) Get an access token and the user’s profile

At this point the user has authorized your application but you don’t have actual access to their data yet. To get that you’ll need to request an access token. Notice that we’re saving the access token to the user’s session as we don’t want to request it more than once during the registration flow.

Once you have the access token, you can then make the request for the user’s profile data:

import urllib
import urllib2
import urlparse
import json
from django.conf import settings
from django.core.urlresolvers import reverse
def get_user_data(request):
data = {}
# if we don't have a token yet, get one now
if 'facebook_access_token' not in request.session:
# URL to where we will redirect to
redirect_url = urllib.quote_plus(settings.SITE_URL + reverse('register_facebook'))
# set the token URL
url = 'https://graph.facebook.com/oauth/access_token?' \
+ 'client_id=' + settings.FACEBOOK_APP_ID \
+ '&redirect_uri=' + redirect_url \
+ '&client_secret=' + settings.FACEBOOK_API_SECRET \
+ '&code=' + request.GET['code']
# grab the token from FB
response = urllib2.urlopen(url).read()
# parse the response
# {'access_token': ['AAAGVChRC0ygBAF3…'], 'expires': ['5183529']}
params = urlparse.parse_qs(response)
# save the token
request.session['facebook_access_token'] = params['access_token'][0]
request.session['facebook_access_expires'] = params['expires'][0]
# set the graph URL using the token we just fetched
graph_url = 'https://graph.facebook.com/me?' \
+ 'access_token=' + request.session['facebook_access_token']
# get the user's data from facebook
response = urllib2.urlopen(graph_url).read()
user = json.loads(response)
# get their photo
# is_silhouette is true if the user has not uploaded a profile picture
graph_url = 'https://graph.facebook.com/me/picture?' \
+ 'type=large' \
+ '&redirect=false' \
+ '&access_token=' + request.session['facebook_access_token']
response = urllib2.urlopen(graph_url).read()
picture = json.loads(response)
# get the user's info
data['user_id'] = user['id']
data['username'] = user['username']
data['email'] = user['email']
data['full_name'] = user['first_name'] + ' ' + user['last_name']
data['first_name'] = user['first_name']
data['last_name'] = user['last_name']
data['timezone'] = user['timezone']
# ensure the user has uploaded a picture
if not picture['data']['is_silhouette']:
data['picture'] = picture['data']['url']
else:
data['picture'] = ''
return data

view raw
facebook.py
hosted with ❤ by GitHub

That’s it! You can now use the user’s profile information to pre-fill a registration form, perhaps skipping over fields where you already have a required value such as an email address or first and last name. Just be sure to save their Facebook ID along with their profile so you can use it validate them in the future. You should also save the access_token and expires values so that you can make future requests to the API for this user or refresh the access token when it has expired.

In a future post I’ll be looking at how to detect an already registered user as well as provide a login with this provider button.

Django Register with Oauth – Disclaimer and Overview

UPDATE… links to all articles…

Facebook – https://chriskief.com/2012/12/22/django-register-with-oauth-facebook/
Twitter – https://chriskief.com/2012/12/22/django-register-with-oauth-twitter/
Google – https://chriskief.com/2012/12/22/django-register-with-oauth-google/
Yahoo! – https://chriskief.com/2012/12/30/django-register-with-oauth-yahoo/
Microsoft – https://chriskief.com/2013/01/05/register-with-oauth-microsoft-live/


First, a couple notes before we begin…

These examples are for server-side implementations, not client-side JavaScript. I’m also going to assume you have some Python / Django experience and will leave it up to you as to how you ultimately structure your code. I’ll also warn that there are probably better ways to do some of this (this is only week 2 of Python for me), but these get the job done so they’ll do for now. I reserve the right to ridicule my own code at some future date.


The flow for each provider is basically the same:

  • Create the URL to redirect to the provider (sometimes this includes fetching a request token)
  • Redirect the user to the provider’s site for approval
  • Handle the response (approved or denied)
  • If the user approved, get an access token
  • Get the user’s profile

Let’s look at Facebook first…

Django Register with Oauth – Facebook, Twitter, Google, Yahoo! and Hotmail (Live)

At first this seems simple enough, allow users to register for your site using one of their existing accounts at popular sites like Facebook, Twitter, Google, Yahoo! and Hotmail (Live). Then you realize that each one has a slightly different oauth implementation, the documentation is not that great, their SDK is out-of-date (looking at you Yahoo), various tutorials on the web are incomplete / out-of-date / simply wrong, or the existing packages provide more functionality than you need (i.e. you’ve already got a user management framework in place).

Over the next couple of posts I will look at getting each one of these up and running. But first, you’ll need to register your application with each provider:

Facebook
https://developers.facebook.com/apps

Twitter
https://dev.twitter.com/apps

Google
https://code.google.com/apis/console/

Yahoo!
https://developer.apps.yahoo.com/projects

Microsoft
http://msdn.microsoft.com/en-us/live/

Once you’ve got all that filled out, add the following to your settings file with their respective values:

TWITTER_CONSUMER_KEY = ''
TWITTER_CONSUMER_SECRET = ''
FACEBOOK_APP_ID = ''
FACEBOOK_API_SECRET = ''
GOOGLE_OAUTH2_CLIENT_ID = ''
GOOGLE_OAUTH2_CLIENT_SECRET = ''
MICROSOFT_CLIENT_ID = ''
MICROSOFT_CLIENT_SECRET = ''
YAHOO_CONSUMER_KEY = ''
YAHOO_CONSUMER_SECRET = ''

view raw
settings.py
hosted with ❤ by GitHub


UPDATE… links to all articles…

Facebook – https://chriskief.com/2012/12/22/django-register-with-oauth-facebook/
Twitter – https://chriskief.com/2012/12/22/django-register-with-oauth-twitter/
Google – https://chriskief.com/2012/12/22/django-register-with-oauth-google/
Yahoo! – https://chriskief.com/2012/12/30/django-register-with-oauth-yahoo/
Microsoft – https://chriskief.com/2013/01/05/register-with-oauth-microsoft-live/