瀏覽代碼

Allowing user to login with Twitter

David Leonard 10 年之前
父節點
當前提交
49959486db

+ 3 - 1
hackathon_starter/hackathon/admin.py

@@ -1,5 +1,7 @@
 from django.contrib import admin
-from hackathon.models import UserProfile
+from hackathon.models import UserProfile, Profile
 
 # Register your models here.
 admin.site.register(UserProfile)
+admin.site.register(Profile)
+

+ 6 - 1
hackathon_starter/hackathon/models.py

@@ -8,4 +8,9 @@ class UserProfile(models.Model):
 
     # Override the __unicode__() method to return out something meaningful!
     def __unicode__(self):
-        return self.user.username
+        return self.user.username
+
+class Profile(models.Model):
+    user = models.ForeignKey(User)
+    oauth_token = models.CharField(max_length=200)
+    oauth_secret = models.CharField(max_length=200)

+ 1 - 1
hackathon_starter/hackathon/templates/hackathon/login.html

@@ -30,7 +30,7 @@
           <i class="fa fa-facebook"></i>
           Sign in with Facebook
         </a>          
-        <a class="btn btn-block btn-social btn-twitter">
+        <a class="btn btn-block btn-social btn-twitter" href="http://127.0.0.1:8000/hackathon/twitter_login/">
           <i class="fa fa-twitter"></i>
           Sign in with Twitter
         </a>

+ 4 - 1
hackathon_starter/hackathon/urls.py

@@ -12,5 +12,8 @@ urlpatterns = patterns('',
     url(r'^steam/$', views.steam, name='steam'),
     url(r'^github/$', views.github, name='github'),
     url(r'^tumblr/$', views.tumblr, name='tumblr'),
-    url(r'^linkedin/$', views.linkedin, name='linkedin')
+    url(r'^linkedin/$', views.linkedin, name='linkedin'),
+    url(r'^twitter_login/?$', views.twitter_login),
+    url(r'^twitter_logout/?$', views.twitter_logout),
+    url(r'^twitter_login/authenticated/?$', views.twitter_authenticated),
 )

+ 90 - 1
hackathon_starter/hackathon/views.py

@@ -1,16 +1,105 @@
+# Django
 from django.shortcuts import render
 from hackathon.forms import UserForm
 from django.contrib.auth import logout
 from django.template import RequestContext, loader
 from django.contrib.auth import authenticate, login
 from django.http import HttpResponse, HttpResponseRedirect
+from django.conf import settings
+from django.shortcuts import render_to_response
+from django.http import HttpResponseRedirect
+from django.conf import settings
+from django.contrib.auth import authenticate, login, logout
+from django.contrib.auth.models import User
+from django.contrib.auth.decorators import login_required
+
+# Scripts
 from scripts.steam import gamesPulling, steamIDPulling 
 from scripts.github import *
 from scripts.tumblr import *
-from django.conf import settings
+
+# Python
+import oauth2 as oauth
+import cgi
+
+# Models
+from hackathon.models import Profile
 
 getTumblr = TumblrOauthClient(settings.TUMBLR_CONSUMER_KEY, settings.TUMBLR_CONSUMER_SECRET)
 
+consumer = oauth.Consumer(settings.TWITTER_TOKEN, settings.TWITTER_SECRET)
+client = oauth.Client(consumer)
+
+request_token_url = 'https://twitter.com/oauth/request_token'
+access_token_url = 'https://twitter.com/oauth/access_token'
+authenticate_url = 'http://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.")
+
+    # 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'])
+    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.")
+    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['screen_name'])
+        print user
+    except User.DoesNotExist:
+        # When creating the user I just use their screen_name@twitter.com
+        # 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['screen_name'],
+            '%s@twitter.com' % access_token['screen_name'],
+            access_token['oauth_token_secret'])
+        print user
+
+        # Save our permanent token and secret for later.
+        profile = Profile()
+        profile.user = user
+        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('/')
+
+
 def index(request):
     context = {'hello': 'world'}
     return render(request, 'hackathon/index.html', context)

+ 2 - 0
hackathon_starter/hackathon_starter/settings.py

@@ -106,4 +106,6 @@ GITHUB_CLIENT_ID = 'client_id=2404a1e21aebd902f6db'
 GITHUB_CLIENT_SECRET = 'client_secret=3da44769d4b7c9465fa4c812669148a163607c23'
 TUMBLR_CONSUMER_KEY = 'KrSbAc9cYLmIgVAn1D21FjRR97QWsutNMxkPDFBxo8CMWtMk4M'
 TUMBLR_CONSUMER_SECRET ='lKWMtL2Lj8zr5pY51PVqT8ugeoG0DjrdgoFewM0QTSyJ12jP8d'
+TWITTER_TOKEN = 'F05dgLAzHEOalb4K2xDQ8Umm8'
+TWITTER_SECRET = 'Yy3a74Z7gvyhxRruJsvUtUl8uK8iv6qKkVqbZSijUxK71Z1qTY'