Skip to content

Commit 7558ec0

Browse files
committed
Added an example of using python-oauth2 to log into Django using Twitter.
1 parent 216a377 commit 7558ec0

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed

README.md

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,158 @@ can be easily translated to a web application.
132132
print
133133
print "You may now access protected resources using the access tokens above."
134134
print
135+
136+
# Logging into Django w/ Twitter
137+
138+
Twitter also has the ability to authenticate a user [via an OAuth flow](http://apiwiki.twitter.com/Sign-in-with-Twitter). This
139+
flow is exactly like the three-legged OAuth flow, except you send them to a
140+
slightly different URL to authorize them.
141+
142+
In this example we'll look at how you can implement this login flow using
143+
Django and python-oauth2.
144+
145+
## Set up a Profile model
146+
147+
You'll need a place to store all of your Twitter OAuth credentials after the
148+
user has logged in. In your app's `models.py` file you should add something
149+
that resembles the following model.
150+
151+
class Profile(models.Model):
152+
user = models.ForeignKey(User)
153+
oauth_token = models.CharField(max_length=200)
154+
oauth_secret = models.CharField(max_length=200)
155+
156+
## Set up your Django views
157+
158+
### `urls.py`
159+
160+
Your `urls.py` should look something like the following. Basically, you need to
161+
have a login URL, a callback URL that Twitter will redirect your users back to,
162+
and a logout URL.
163+
164+
In this example `^login/` and `twitter_login` will send the user to Twitter to
165+
be logged in, `^login/authenticated/` and `twitter_authenticated` will confirm
166+
the login, create the account if necessary, and log the user into the
167+
application, and `^logout`/ logs the user out in the `twitter_logout` view.
168+
169+
170+
from django.conf.urls.defaults import *
171+
from django.contrib import admin
172+
from mytwitterapp.views import twitter_login, twitter_logout, \
173+
twitter_authenticated
174+
175+
admin.autodiscover()
176+
177+
urlpatterns = patterns('',
178+
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
179+
url(r'^admin/', include(admin.site.urls)),
180+
url(r'^login/?$', twitter_login),
181+
url(r'^logout/?$', twitter_logout),
182+
url(r'^login/authenticated/?$', twitter_authenticated),
183+
)
184+
185+
### `views.py`
186+
187+
*NOTE:* The following code was coded for Python 2.4 so some of the libraries
188+
and code here might need to be updated if you are using Python 2.6+.
189+
190+
# Python
191+
import oauth2 as oauth
192+
import cgi
193+
194+
# Django
195+
from django.shortcuts import render_to_response
196+
from django.http import HttpResponseRedirect
197+
from django.conf import settings
198+
from django.contrib.auth import authenticate, login, logout
199+
from django.contrib.auth.models import User
200+
from django.contrib.auth.decorators import login_required
201+
202+
# Project
203+
from mytwitterapp.models import Profile
204+
205+
consumer = oauth.Consumer(settings.TWITTER_TOKEN, settings.TWITTER_SECRET)
206+
client = oauth.Client(consumer)
207+
208+
request_token_url = 'http://twitter.com/oauth/request_token'
209+
access_token_url = 'http://twitter.com/oauth/access_token'
210+
211+
# This is the slightly different URL used to authenticate/authorize.
212+
authenticate_url = 'http://twitter.com/oauth/authenticate'
213+
214+
def twitter_login(request):
215+
# Step 1. Get a request token from Twitter.
216+
resp, content = client.request(request_token_url, "GET")
217+
if resp['status'] != '200':
218+
raise Exception("Invalid response from Twitter.")
219+
220+
# Step 2. Store the request token in a session for later use.
221+
request.session['request_token'] = dict(cgi.parse_qsl(content))
222+
223+
# Step 3. Redirect the user to the authentication URL.
224+
url = "%s?oauth_token=%s" % (authenticate_url,
225+
request.session['request_token']['oauth_token'])
226+
227+
return HttpResponseRedirect(url)
228+
229+
230+
@login_required
231+
def twitter_logout(request):
232+
# Log a user out using Django's logout function and redirect them
233+
# back to the homepage.
234+
logout(request)
235+
return HttpResponseRedirect('/')
236+
237+
def twitter_authenticated(request):
238+
# Step 1. Use the request token in the session to build a new client.
239+
token = oauth.Token(request.session['request_token']['oauth_token'],
240+
request.session['request_token']['oauth_token_secret'])
241+
client = oauth.Client(consumer, token)
242+
243+
# Step 2. Request the authorized access token from Twitter.
244+
resp, content = client.request(access_token_url, "GET")
245+
if resp['status'] != '200':
246+
print content
247+
raise Exception("Invalid response from Twitter.")
248+
249+
"""
250+
This is what you'll get back from Twitter. Note that it includes the
251+
user's user_id and screen_name.
252+
{
253+
'oauth_token_secret': 'IcJXPiJh8be3BjDWW50uCY31chyhsMHEhqJVsphC3M',
254+
'user_id': '120889797',
255+
'oauth_token': '120889797-H5zNnM3qE0iFoTTpNEHIz3noL9FKzXiOxwtnyVOD',
256+
'screen_name': 'heyismysiteup'
257+
}
258+
"""
259+
access_token = dict(cgi.parse_qsl(content))
260+
261+
# Step 3. Lookup the user or create them if they don't exist.
262+
try:
263+
user = User.objects.get(username=access_token['screen_name'])
264+
except User.DoesNotExist:
265+
# When creating the user I just use their [email protected]
266+
# for their email and the oauth_token_secret for their password.
267+
# These two things will likely never be used. Alternatively, you
268+
# can prompt them for their email here. Either way, the password
269+
# should never be used.
270+
user = User.objects.create_user(access_token['screen_name'],
271+
'%[email protected]' % access_token['screen_name'],
272+
access_token['oauth_token_secret'])
273+
274+
# Save our permanent token and secret for later.
275+
profile = Profile()
276+
profile.user = user
277+
profile.oauth_token = access_token['oauth_token']
278+
profile.oauth_secret = access_token['oauth_token_secret']
279+
profile.save()
280+
281+
# Authenticate the user and log them in using Django's pre-built
282+
# functions for these things.
283+
user = authenticate(username=access_token['screen_name'],
284+
password=access_token['oauth_token_secret'])
285+
login(request, user)
286+
287+
return HttpResponseRedirect('/')
288+
289+

0 commit comments

Comments
 (0)