Twitter authentication API

Let's create our project, twit:
$ django-admin.py startproject twit

Modify settings.py:
INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', ... 'twitapp', ) DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'name', 'USER': 'username', 'PASSWORD': 'mypassword', 'HOST': 'localhost', # Or an IP Address that your DB is hosted on 'PORT': '3306', } }
Let's make a Django Application (twitapp):
$ python manage.py startapp twitapp
twit/urls.py:
from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', url(r'^$', 'twitapp.views.home', name='home'), url(r'^admin/', include(admin.site.urls)), )
twitapp/urls.py:
Nothing in it.
twitapp/views.py:
# twitapp/views.py from django.shortcuts import render_to_response from django.template.context import RequestContext def home(request): context = RequestContext(request, {'user': request.user}) return render_to_response('home.html', context_instance=context)
twitapp/templates/base.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>{% block title %}Bogo Twit Authentication Tutorial{% endblock %}</title> <!-- Bootstrap --> <link href="/static/css/bootstrap.min.css" rel="stylesheet"> <link href="/static/css/bootstrap-theme.min.css" rel="stylesheet"> <link href="/static/css/fbposter.css" rel="stylesheet"> <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> <![endif]--> </head> <body> {% block main %}{% endblock %} <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <!-- Include all compiled plugins (below), or include individual files as needed --> <script src="/static/js/bootstrap.min.js"></script> </body> </html>
twitapp/templates/home.html:
{% extends 'base.html' %} {% block main %} <div> <h1>Bogo Twitter authentication demo</h1> <p> {% if user and not user.is_anonymous %} Hello {{ user.get_full_name|default:user.username }}! {% else %} I don't think you're authorized. {% endif %} </p> </div> {% endblock %}
At this point, our project structure looks like this:

First, I made a directory www/bogotwit, and under the directory, I have the following two files:
[~/www/bogotwit]# ls ./ ../ .htaccess myfcgi.fcgi*
myfcgi.fcgi:
#! /home2/bogotob1/python/bin/python import sys, os sys.path.insert(0, "/home2/bogotob1/python") sys.path.insert(13, "/home2/bogotob1/DJ/twit") sys.path.append("/home2/bogotob1/python/lib/python2.7/site-packages/") os.environ['DJANGO_SETTINGS_MODULE'] = 'twit.settings' from django.core.servers.fastcgi import runfastcgi runfastcgi(method="threaded", daemonize="false")
.htaccess:
# django AddHandler fcgid-script .fcgi RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f #RewriteCond %{REQUEST_URI} !^/static/ RewriteRule ^(.*)$ myfcgi.fcgi/$1 [QSA,L]
Now, I have a new page:

Let's install django-social-auth:
$ pip install python-social-auth
It will be installed as ~/python/lib/python2.7/site-packages/social_auth/.
In twit/settings.py, we should include "Python social auth" in our project:
INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'twitapp', 'social_auth', ) TEMPLATE_CONTEXT_PROCESSORS = ( 'django.contrib.auth.context_processors.auth', 'django.core.context_processors.debug', 'django.core.context_processors.i18n', 'django.core.context_processors.media', 'django.core.context_processors.static', 'django.core.context_processors.tz', 'django.contrib.messages.context_processors.messages', 'social_auth.context_processors.social_auth_by_type_backends', ) AUTHENTICATION_BACKENDS = ( 'social_auth.backends.twitter.TwitterBackend', 'social_auth.backends.facebook.FacebookBackend', 'social_auth.backends.google.GoogleOAuthBackend', 'social_auth.backends.google.GoogleOAuth2Backend', 'social_auth.backends.google.GoogleBackend', 'social_auth.backends.yahoo.YahooBackend', 'social_auth.backends.browserid.BrowserIDBackend', 'social_auth.backends.contrib.linkedin.LinkedinBackend', 'social_auth.backends.contrib.disqus.DisqusBackend', 'social_auth.backends.contrib.livejournal.LiveJournalBackend', 'social_auth.backends.contrib.orkut.OrkutBackend', 'social_auth.backends.contrib.foursquare.FoursquareBackend', 'social_auth.backends.contrib.github.GithubBackend', 'social_auth.backends.contrib.vk.VKOAuth2Backend', 'social_auth.backends.contrib.live.LiveBackend', 'social_auth.backends.contrib.skyrock.SkyrockBackend', 'social_auth.backends.contrib.yahoo.YahooOAuthBackend', 'social_auth.backends.contrib.readability.ReadabilityBackend', 'social_auth.backends.contrib.fedora.FedoraBackend', 'social_auth.backends.OpenIDBackend', 'django.contrib.auth.backends.ModelBackend', )
We also need to update the twit/urls.py to include the new group of URLs:
from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', url(r'^$', 'twitapp.views.home', name='home'), url(r'', include('social_auth.urls')), url('', include('django.contrib.auth.urls', namespace='auth')), url(r'^admin/', include(admin.site.urls)), )
The last thing to do is to update our data model:
$ python manage.py syncdb
To handle static files in production, we need to adjust the 'STATIC_URL':
STATIC_URL = '/bogotwit/static/'
Set the STATIC_ROOT to the directory from which we like to serve these files. So, when we do collectstatic, it will copy all files from our static folders into the STATIC_ROOT directory. In my case, it is:
STATIC_ROOT = "/home2/bogotob1/www/bogotwit/static/"
Then, run collectstatic to have all necessary files to our STATIC_ROOT:
$ python manage.py collectstatic
If we open our browser, and type in the url as shown in the picture, we get:

After login:

As we can see from the picture, we have three new tables: Associations, Nonces, and User social auths. This last one will contain the records of our usersâ social accounts when they use social networks to authenticate from our app.
We're getting there!
Letâs add some links for logging in and logging out, and then weâll start adding application IDs for social apps.
Put django.contrib.auth.urls into our URLs configuration:
urlpatterns = patterns('', ... url('', include('django.contrib.auth.urls', namespace='auth')), ... )
Let's modify our home page template (twitapp/templates/home.html) like this:
{% extends 'base.html' %} {% block main %} <div> <h1>Bogo authentication API demo</h1> <p> <ul> {% if user and not user.is_anonymous %} <li> <a>Hello {{ user.get_full_name|default:user.username }}!</a> </li> <li> <a href="{% url 'auth:logout' %}?next={{ request.path }}">Logout</a> </li> {% else %} <li> <a href="{% url 'socialauth_begin' 'facebook' %}?next={{ request.path }}">Login with Facebook</a> </li> <li> <a href="{% url 'socialauth_begin' 'google-oauth2' %}?next={{ request.path }}">Login with Google</a> </li> <li> <a href="{% url 'socialauth_begin' 'twitter' %}?next={{ request.path }}">Login with Twitter</a> </li> {% endif %} </ul> </p> </div> {% endblock %}
Now, we get this:

For all the social networks we are using in this demo, the process of obtaining an OAuth2 client ID (also known as application ID) is pretty similar. All of them will require that your application has a ârealâ URL not "localhost"
Facebook:
- Go to https://developers.facebook.com/apps/?action=create and click the green "Create New App" button.
- Copy the App ID and App Secret, and place them into settings.py file:
TWITTER_CONSUMER_KEY = '' TWITTER_CONSUMER_SECRET = '' FACEBOOK_APP_ID = '14************16' FACEBOOK_API_SECRET = 'e******************************9' LINKEDIN_CONSUMER_KEY = '' LINKEDIN_CONSUMER_SECRET = '' GOOGLE_CONSUMER_KEY = '' GOOGLE_CONSUMER_SECRET = '' GOOGLE_OAUTH2_CLIENT_ID = '' GOOGLE_OAUTH2_CLIENT_SECRET = ''
- In the settings of the newly-created application, click "Add Platform". From the options provided, choose Web, and fill in the URL of the site (http://bogotobogo.com in our example).

After click "OK", we may get the following error:
TypeError at /complete/facebook/
datetime.datetime(...)is not JSON serializable
Then, we need the a line in settings.py
SESSION_SERIALIZER='django.contrib.sessions.serializers.PickleSerializer'
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization