django-social-auth Setup

1. Install the app

pip install django-social-auth and wait a few minutes. This is a good time to get your API keys set up with Twitter, Facebook, whatever.

2. settings.py, where the work is really done

  1. Once it’s installed, add it to your INSTALLED_APPS.

  2. Add 'social_auth.context_processors.social_auth_by_type_backends' to your TEMPLATE_CONTEXT_PROCESSORS. Yes, this means you probably have to go look them up in Django’s documentation so that you don’t override the defaults (why isn’t this in there by default?) but that’s OK.

  3. Then comes a big block of settings. I usually put these at the end:

    # SOCIAL AUTH SETTINGS
    TWITTER_CONSUMER_KEY = 'your-key-here'
    TWITTER_CONSUMER_SECRET = 'your-secret-here'
    FACEBOOK_APP_ID = 'your-id-here'
    FACEBOOK_API_SECRET = 'your-secret-here'
    SOCIAL_AUTH_ENABLED_BACKENDS = ('facebook', 'twitter')
    SOCIAL_AUTH_COMPLETE_URL_NAME = 'socialauth_complete'
    SOCIAL_AUTH_ASSOCIATE_URL_NAME = 'associate_complete'
    SOCIAL_AUTH_DEFAULT_USERNAME = lambda u: slugify(u) # you'll need to import slugify from 'django.template.defaultfilters'
    SOCIAL_AUTH_EXTRA_DATA = False
    SOCIAL_AUTH_CHANGE_SIGNAL_ONLY = True
    
    AUTHENTICATION_BACKENDS = (
        'social_auth.backends.twitter.TwitterBackend',
        'social_auth.backends.facebook.FacebookBackend',
        'django.contrib.auth.backends.ModelBackend',
    )
    
    LOGIN_URL = '/login/'
    LOGIN_REDIRECT_URL = '/'
    LOGIN_ERROR_URL = '/login-error/'
    
  4. Next, edit urls.py and add in url(r'', include('social_auth.urls')).

  5. You’ll want to set up some HTML links for people to login through:

    <li><a href="{% url socialauth_begin 'twitter' %}">Login with Twitter</a></li>
    <li><a href="{% url socialauth_begin 'facebook' %}">Login with Facebook</a></li>

3. Explanations of a few bits

In the 3rd step above, you can configure a few things differently if you want.

  1. SOCIAL_AUTH_ENABLED_BACKENDS needs to match the backends that you add to AUTHENTICATION_BACKENDS. This lets you only load the backends you need.
  2. Sadly, SOCIAL_AUTH_COMPLETE_URL_NAME and SOCIAL_AUTH_ASSOCIATE_URL_NAME seem to be magic settings with the last release. Just set them to this and don’t worry about it unless you want to.
  3. SOCIAL_AUTH_DEFAULT_USERNAME lets you set up a default username. You’ll get one from the social auth service but it may not be compatible with Django’s username requirements, hence the use of slugify(). You could also use string.alphabet and some randomness to make a string for them.
  4. Lastly, SOCIAL_AUTH_CHANGE_SIGNAL_ONLY stops the 3rd party apps from overriding anything the user has now entered in their User instance. For example, Twitter returns a user’s full name as Django’s first_name. This means if you let them set first & last name, Twitter will override it each time they login. The SOCIAL_AUTH_EXTRA_DATA setting tells the backends we don’t want any extra data they send through. If, though, you do want the data, obviously turn this off.

4. Extra stuff

Not something I use often, but you can set up signals for after a user logs in/signs up:

from social_auth.signals import pre_update
from social_auth.backends.twitter import TwitterBackend

def twitter_user_update(sender, user, response, details, **kwargs):
    profile, create = Profile.objects.get_or_create(user=user)
    profile.image = response['profile_image_url']

    tokens = response['access_token'].split('&')
    profile.oauth_token_secret = tokens[0].split('=')[-1]
    profile.oauth_token = tokens[1].split('=')[-1]

    if user.username != response['screen_name']:
        redirect = Redirect.objects.get(new_path=profile.get_absolute_url())
    else:
        redirect = False

    profile.user.username = response['screen_name']
    if create:
        profile.point = generate_point(lat=0, lng=0)
    profile.save()
    user.username = response['screen_name']
    user.save()

    if redirect:
        redirect.new_path = profile.get_absolute_url()
        redirect.save()

    return True

pre_update.connect(twitter_user_update, sender=TwitterBackend)

This should be pretty self-explanatory if you’re used to using signals in Django. This one, each time a user logs in, overrides their username and saves their tokens so we can post to Twitter as them.

If you have any questions, hit me up on Twitter as @kennethlove

Table Of Contents

Previous topic

PDX Python Meetup

This Page