DjangoCon 2011 Notes / docs / django_social_auth.rst

Kenneth Love 4d66fa9 

Kenneth Love d5f8971 

Kenneth Love 4d66fa9 

Kenneth Love f822b3f 
Kenneth Love 4d66fa9 

``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. ````, 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::

        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'


        LOGIN_URL = '/login/'
        LOGIN_REDIRECT_URL = '/'
        LOGIN_ERROR_URL = '/login-error/'

    4. Next, edit ```` 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())
                redirect = False

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

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

            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