Skip to content

Instantly share code, notes, and snippets.

@qqpann
Created June 30, 2018 12:29
Show Gist options
  • Save qqpann/42a15910e74e8efd4ad708009b96e50c to your computer and use it in GitHub Desktop.
Save qqpann/42a15910e74e8efd4ad708009b96e50c to your computer and use it in GitHub Desktop.
Use Django to authenticate with Twitter.
import cgi
import os
import oauth2 as oauth
from django.conf import settings
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from listter.models import Profile
# It's probably a good idea to put your consumer's OAuth token and
# OAuth secret into your project's settings.
consumer = oauth.Consumer(
os.environ.get('TWITTER_LISTTER_CONSUMER_KEY', ''),
os.environ.get('TWITTER_LISTTER_CONSUMER_SECRET', ''),
)
client = oauth.Client(consumer)
request_token_url = 'https://api.twitter.com/oauth/request_token'
if settings.DEBUG:
request_token_url += '?oauth_callback=http://localhost:8000/listter/login/authenticated'
access_token_url = 'https://api.twitter.com/oauth/access_token'
# This is the slightly different URL used to authenticate/authorize.
authenticate_url = 'https://api.twitter.com/oauth/authenticate'
def twitter_login(request):
# Step 1. Get a request token from Twitter.
resp, content = client.request(request_token_url, "GET")
if resp['status'] != '200':
raise Exception("Invalid response from Twitter.")
if content.__class__ is bytes:
content = content.decode('ascii')
# Step 2. Store the request token in a session for later use.
request.session['request_token'] = dict(cgi.parse_qsl(content))
# Step 3. Redirect the user to the authentication URL.
url = "%s?oauth_token=%s" % (authenticate_url,
request.session['request_token']['oauth_token'])
return HttpResponseRedirect(url)
@login_required
def twitter_logout(request):
# Log a user out using Django's logout function and redirect them
# back to the homepage.
logout(request)
return HttpResponseRedirect('/')
def twitter_authenticated(request):
# Step 1. Use the request token in the session to build a new client.
token = oauth.Token(request.session['request_token']['oauth_token'],
request.session['request_token']['oauth_token_secret'])
token.set_verifier(request.GET['oauth_verifier'])
client = oauth.Client(consumer, token)
# Step 2. Request the authorized access token from Twitter.
resp, content = client.request(access_token_url, "GET")
if resp['status'] != '200':
print(content)
raise Exception("Invalid response from Twitter.")
if content.__class__ is bytes:
content = content.decode('ascii')
"""
This is what you'll get back from Twitter. Note that it includes the
user's user_id and screen_name.
{
'user_id': '120889797',
'screen_name': 'heyismysiteup'
'oauth_token': '120889797-H5zNnM3qE0iFoTTpNEHIz3noL9FKzXiOxwtnyVOD',
'oauth_token_secret': 'IcJXPiJh8be3BjDWW50uCY31chyhsMHEhqJVsphC3M',
}
"""
access_token = dict(cgi.parse_qsl(content))
# Step 3. Lookup the user or create them if they don't exist.
try:
user = User.objects.get(username=access_token['user_id'])
except User.DoesNotExist:
# When creating the user I just use their [email protected]
# for their email and the oauth_token_secret for their password.
# These two things will likely never be used. Alternatively, you
# can prompt them for their email here. Either way, the password
# should never be used.
user = User.objects.create_user(access_token['user_id'],
'%[email protected]' % access_token['screen_name'],
access_token['oauth_token_secret'])
# Save our permanent token and secret for later.
profile = Profile()
profile.user = user
Profile.screen_name = access_token['screen_name']
profile.oauth_token = access_token['oauth_token']
profile.oauth_secret = access_token['oauth_token_secret']
profile.save()
# Authenticate the user and log them in using Django's pre-built
# functions for these things.
user = authenticate(username=access_token['screen_name'],
password=access_token['oauth_token_secret'])
login(request, user)
return HttpResponseRedirect('/')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment