@@ -132,3 +132,158 @@ can be easily translated to a web application.
132
132
print
133
133
print "You may now access protected resources using the access tokens above."
134
134
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