1. David Larlet
  2. django-oauth-plus


Clone wiki

django-oauth-plus / consumer_example

OAuth flow example (consumer side tutorial)

This page provides simple tutorial on consumer side OAuth authentication.

Note that this example should show you how OAuth works and is not django-oauth-plus specific. If you need deeper insight on how it works internally in django-oauth-plus please take a look on older version of this tutorial.

OAuth Authentication is done in three steps:

  1. The Consumer obtains an unauthorized Request Token.
  2. The User authorizes the Request Token.
  3. The Consumer exchanges the Request Token for an Access Token.

This page shows example interaction with oauth_provider on consumer side

Initial assumptions

In this tutorial we will use following terms:

Provider - Web application providing OAuth authentication for accessing it's resources.

Consumer - Application accessing OAuth protected resources on behalf of User.

User - User of Provider's application. Has access to some resources and can grant them to Consumer.

For the purpose of this example we need some basic assumptions. The Service Provider documentation explains how to register for a Consumer Key and Consumer Secret, and declares the following URLs:

Request Token URL: http://photos.example.net/request_token/, using HTTP POST

User Authorization URL: http://photos.example.net/authorize/, using HTTP GET

Access Token URL: http://photos.example.net/access_token/, using HTTP POST

Photo (Protected Resource) URL: http://photos.example.net/photo with required parameter file and optional parameter size

The Service Provider declares support for the HMAC-SHA1 signature method for all requests, and PLAINTEXT only for secure (HTTPS) requests.

The Consumer printer.example.com already established a Consumer Key and Consumer Secret with photos.example.net and advertizes its printing services for photos stored on photos.example.net. The Consumer registration is:

  • Consumer Key: dpf43f3p2l4k3l03
  • Consumer Secret: kd94hf93k423kf44

Step 1. Obtaining a Request Token

Note: In further code examples we will use python-oauth2 and python-requests for making OAuth signed requests. There is a plenty of other tools you can use to communicate with different APIs (like slumber) but oauth2 should still remain useful in signing OAuth requests.

After User informs printer.example.com that she would like to print her vacation photo stored at photos.example.net the Consumer website tries to access the photo and receives HTTP 401 Unauthorized indicating it is private. The Service Provider includes the following header with the response:

WWW-Authenticate: OAuth realm=""

Consumer must obtain unsigned request token in order to start authentication flow (referred sometimes as 'OAuth dance'):

import urlparse
import oauth2 as oauth
import requests

request_token_url = 'http://photos.example.net/request_token/'
callback_url = 'http://printer.example.com/request_token_ready' # 'oob' if no callback

consumer = oauth.Consumer(key='dpf43f3p2l4k3l03', secret='kd94hf93k423kf44')
#create and sing request
oauth_request = oauth.Request.from_consumer_and_token(consumer, http_url=request_token_url, parameters={'oauth_callback':callback_url})
oauth_request.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None)

response = requests.get(request_token_url, headers=oauth_request.to_header())
request_token = dict(urlparse.parse_qsl(response.content))
# - oauth_token:        request_token['oauth_token']
# - oauth_token_secret: request_token['oauth_token_secret']

Note: In this example we use HMAC_SHA1 signing method. This method includes request URL to signing base. You should be aware of this fact because requests.get() automatically follows redirects. If this happen your request will fail to authenticate because it will be signed with wrong URL and signature won't be validated. If you don't want to handle redirects just make sure that you use URLs that don't result in redirects.

Step 2. Authorizing the Request Token

In this step User have to authorize your access token. In order to do this you must redirect him to authorization URL with oauth_token as a GET parameter. In this case it will be:

'http://photos.example.net/authorize?oauth_token=%s' % request_token['oauth_token']

User after granting access to his resources will be redirected back to callback url specified when obtaining request token. This is the way Consumer can get from Provider two parameters:

  • oauth_token
  • oauth_verifier

Step 3. Exchanging Request Token for Access Token

Once the Provider has redirected the User back to the oauth_callback URL Consumer can request the access token the User has approved. Consumer uses the request token to sign his request. After this is done he throw away therequest token and use the access token returned. This access token should be stored somewhere safe, like a database, for future use.

access_token_url = 'http://photos.example.net/access_token/'

token = oauth.Token(request_token['oauth_token'], request_token['oauth_token_secret'])
oauth_request = oauth.Request.from_consumer_and_token(consumer, http_url=access_token_url)
oauth_request.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, token)

response = requests.get(access_token_url, headers=oauth_request.to_header())
access_token = dict(urlparse.parse_qsl(response.content))
# - oauth_token:        access_token['oauth_token']
# - oauth_token_secret: access_token['oauth_token_secret']

Using access token

Access token can now be used for signing all further requests to OAuth protected resources.

resource_url = 'http://photos.example.net/photo'

token = oauth.Token(access_token['oauth_token'], access_token['oauth_token_secret'])
oauth_request = oauth.Request.from_consumer_and_token(consumer, http_url=resource_url)
oauth_request.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None)

# get the resource
response = requests.get(resource_url, headers=oauth_request.to_header())