
Step by Step Guide to use Sign in with Twitter with Django
April 28, 2009If you will have a look at OAuth examples on twitter apiwiki there are already examples available to use Sign in with Twitter with Django, so why this new howto and example code. Because being a perfectionist I like things to be the standard way, so for authentication django allows you to specify your own customized authentication backends. I thought why should not that be utilized to authenticate the Django User object with twitter.
There are few pre-requisites listed below in the order they are needed:
- simplejson
- oauth
- python-twitter
- oauth-python-twitter
- TwitterBackend from djangosnippets.org
This guide assumes that simplejson, oauth, python-twitter and oauth-python-twitter are already on your python path.
1. Now create a new Django project: twitterapp
django-admin startproject
2. Change to the project directory.
3. Now start a new app inside the project
python manage.py startapp twitterauth
4. Create a new directory: backends
mkdir backends
5. Change to the backends directory and create 2 new empty files.
cd backends
touch __init__.py
touch twitteroauth.py
6. Copy the code from TwitterBackend into the empty file: twitteroauth.py
7. Now configure your settings.py and add/edit following configuration variables
CONSUMER_KEY = "Your consumer key from twitter"
CONSUMER_SECRET = "You consumer secret from twitter"
AUTHENTICATION_BACKENDS = (
'backends.twitteroauth.TwitterBackend',
'django.contrib.auth.backends.ModelBackend',
)
AUTH_PROFILE_MODULE = "twitterauth.UserProfile"
8. Now goto the twitterauth app directory and create a UserProfile module and post save signal processor as follows:
from django.db import models from django.db.models.signals import post_save from django.contrib.auth.models import User class UserProfile(models.Model): user = models.ForeignKey(User) access_token = models.CharField(max_length=255, blank=True, null=True, editable=False) profile_image_url = models.URLField(blank=True, null=True) location = models.CharField(max_length=100, blank=True, null=True) url = models.URLField(blank=True, null=True) description = models.CharField(max_length=160, blank=True, null=True) def __str__(self): return "%s's profile" % self.user def create_user_profile(sender, instance, created, **kwargs): if created: profile, created = UserProfile.objects.get_or_create(user=instance) post_save.connect(create_user_profile, sender=User)
9. Now modify your views.py in twitterauth app directory as following:
from django.conf import settings
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth import login, authenticate
from oauthtwitter import OAuthApi
import oauth
CONSUMER_KEY = getattr(settings, 'CONSUMER_KEY', 'YOUR_KEY')
CONSUMER_SECRET = getattr(settings, 'CONSUMER_SECRET', 'YOUR_SECRET')
def twitter_signin(request):
twitter = OAuthApi(CONSUMER_KEY, CONSUMER_SECRET)
request_token = twitter.getRequestToken()
request.session['request_token'] = request_token.to_string()
signin_url = twitter.getSigninURL(request_token)
return HttpResponseRedirect(signin_url)
def twitter_return(request):
request_token = request.session.get('request_token', None)
# If there is no request_token for session,
# means we didn't redirect user to twitter
if not request_token:
# Redirect the user to the login page,
# So the user can click on the sign-in with twitter button
return HttpResponse("We didn't redirect you to twitter...")
token = oauth.OAuthToken.from_string(request_token)
# If the token from session and token from twitter does not match
# means something bad happened to tokens
if token.key != request.GET.get('oauth_token', 'no-token'):
del request.session['request_token']
# Redirect the user to the login page
return HttpResponse("Something wrong! Tokens do not match...")
twitter = OAuthApi(CONSUMER_KEY, CONSUMER_SECRET, token)
access_token = twitter.getAccessToken()
request.session['access_token'] = access_token.to_string()
auth_user = authenticate(access_token=access_token)
# if user is authenticated then login user
if auth_user:
login(request, auth_user)
else:
# We were not able to authenticate user
# Redirect to login page
del request.session['access_token']
del request.session['request_token']
return HttpResponse("Unable to authenticate you!")
# authentication was successful, use is now logged in
return HttpResponse("You are logged in")
10. Add the following 2 lines to urls.py at correct location.
url('^login/$', twitter_signin, name='login'),
url('^return/$', twitter_return, name='return'),
11. Now start the django devevelopment server
python manage.py runserver
12. Goto http://localhost:8000/login and you will be redirected to user for authentication, and if everything wents well you will see the message that your are logged in.














I ran across your blog and it is exactly what I am looking for. I was following your steps and have ran into an issue with the oauth plugin it seems. I was wondering if you have any idea about the following message:
>>> import oauth
>>> import twitter
>>> import oauthtwitter
Traceback (most recent call last):
File “”, line 1, in
File “/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/oauthtwitter.py”, line 30, in
class OAuthApi(Api):
File “/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/oauthtwitter.py”, line 148, in OAuthApi
def _signRequest(self, req, signature_method=oauth.OAuthSignatureMethod_HMAC_SHA1()):
AttributeError: ‘module’ object has no attribute ‘OAuthSignatureMethod_HMAC_SHA1′
oAuth imports fine but when I try to import oauthtwitter. I get that error from command line. Any help would be glady appreciated.
Dev Box:
OS X 10.5
Python 2.5.4
Django 1.0.2
Thanks in advance
Hello Eric,
I am glad you were able to find what you needed. You really do not have to import oauth and twitter unless you want to use them directly.
So, you can just do:
import oauthtwitter
The error is I think because you might be using some other version of the oauth. Kindly please download the version of oauth that is listed at the top of the post and use that version. Because twitter only support HMAC-SHA1 based oauth signatures. So you have to have that class in your implementation of oauth. The version that is listed above has it.
I hope it will help you.
I had this problem too. I get it when I used setuptools to install an egg of ouath. Instead, just copy oauth.py into your Python path and it will work fine.
Thank you very much for the nice implementaion.
I stated using it and i like it very much.
I keep running into one strange issue:
Every once in a while a user gets the following when returning from twitter error:
“We didn’t redirect you to twitter…”
Which means that for some reason there was no ‘request_token’ key in the session.
Any ideas what may cause this?
Hmm.. this is strange, if user is properly redirected to twitter as in twitter_signin view then they should have request_token in their session.
Might be user’s browser clearing up cookies?
There is nothing else I can think of right now, but I will look into it and will let you know if I will find something, but I didn’t face this yet on my end.
This is also happening to me. I am sniffing the traffic and I can’t see anything weird, twitter just doesn’t seem to be setting the request_token. I’ve tried multiple different twitter users and different browsers.
Hi,
I’m having an issue with the implementation. I get the following error:
AttributeError at /login/
‘OAuthApi’ object has no attribute ‘_default_params’
Exception Location: oauthtwitter.py in _FetchUrl, line 70
And for return I get No un-authed token cookie.
Any assistance would be greatly appreciated.
Great work and had a question. I’m new to Django. I did not understand step 8 where you state “create a UserProfile module and post save signal processor as follows:”
Does this mean
1.create a module UserProfile.py
2.Add the below code to UserProfile.py
or
1.Create a module UserProfile.py
2.Add the below code to a file Models.py and do sync db
Thanks for pointing that out, that should be create UserProfile model. Will fix it now.
I am still very confused by where UserProfile goes and the specifics here.
I get a similar error as here: http://groups.google.com/group/django-users/browse_thread/thread/8494cd87bf181018/e73fed4cdbd80a4e
and I can’t figure out how to solve it.
Thanks for this!
Everything seems to work except for when i return from twitter i get an exception (type ProgrammingError) “can’t adapt ” in backends/twitteroauth.py line 57 ( ” userprofile.save() “)
Anyone got some ideas how to fix this?
Thanks in advance!!
Hi I have the same issue. Did you manage to resolve this?
I am trying to use this implementation and have gotten pretty far, except that when twitter redirects back, I am getting an error because the UserProfile table is not in the database. Perhaps I am not reading the instructions correctly, but I created the file called UserProfile.py in the twitterauth directory. But when I run manage.py syncdb, it is not creating the UserProfile. Obviously I’m missing something. Can anyone help?
Thanks,
JoeCascio
ps. Here’s the traceback:
Traceback Switch to copy-and-paste view
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/core/handlers/base.py in get_response
response = callback(request, *callback_args, **callback_kwargs) …
▶ Local vars
/Users/joecascio/projects/utwility/../utwility/twitterauth/views.py in twitter_return
auth_user = authenticate(access_token=access_token) …
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/contrib/auth/__init__.py in authenticate
user = backend.authenticate(**credentials) …
▶ Local vars
/Users/joecascio/projects/utwility/backends/twitteroauth.py in authenticate
userprofile = user.get_profile() …
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/contrib/auth/models.py in get_profile
if not hasattr(self, ‘_profile_cache’):
from django.conf import settings
if not getattr(settings, ‘AUTH_PROFILE_MODULE’, False):
raise SiteProfileNotAvailable
try:
app_label, model_name = settings.AUTH_PROFILE_MODULE.split(‘.’)
model = models.get_model(app_label, model_name)
self._profile_cache = model._default_manager.get(user__id__exact=self.id) …
self._profile_cache.user = self
except (ImportError, ImproperlyConfigured):
raise SiteProfileNotAvailable
return self._profile_cache
class Message(models.Model):
▼ Local vars
Variable Value
app_label
‘twitterauth’
model
None
model_name
‘UserProfile’
self
settings
I got past that bug with the help of the previous comments and answers. But then I ran into trouble when ‘twitter_return’ tried to save the UserProfile in the database. In filling in the query params deep down in the ORM code. The oauth.OAuthToken was being passed as the access token string. I think this change needs to be made in twitteroauth.py line 54 needs to have the to_string() function applied.
Original:
userprofile.access_token = access_token
Modified:
userprofile.access_token = access_token.to_string()
This is required because userprofile.access_token is a CharField.