Django Social Auth is an easy to setup social authentication/authorization mechanism for Django projects.
Crafted using base code from django-twitter-oauth and django-openid-auth, implements a common interface to define new authentication providers from third parties.
You can check this documentation on Read the Docs too.
Table of Contents
There's a demo at http://social.matiasaguirre.net/. Note: It lacks some backends support at the moment.
This application provides user registration and login using social sites credentials, some features are:
Registration and Login using social sites using the following providers at the moment:
Some contributions added support for:
Basic user data population and signaling, to allows custom fields values from providers response
Multiple social accounts association to single users
Custom User model override if needed (auth.User by default)
Extensible pipeline to handle authentication/association mechanism
Dependencies that must be meet to use the application:
- OpenId support depends on python-openid
- OAuth support depends on python-oauth2
- Several backends demands application registration on their corresponding sites.
From pypi:
$ pip install django-social-auth
or:
$ easy_install django-social-auth
or clone from github:
$ git clone git://github.com/omab/django-social-auth.git
and add social_auth to PYTHONPATH:
$ export PYTHONPATH=$PYTHONPATH:$(pwd)/django-social-auth/
or:
$ cd django-social-auth $ sudo python setup.py install
Add social_auth to
PYTHONPATH
and installed applications:INSTALLED_APPS = ( ... 'social_auth' )
Add desired authentication backends to Django's AUTHENTICATION_BACKENDS setting:
AUTHENTICATION_BACKENDS = ( 'social_auth.backends.twitter.TwitterBackend', 'social_auth.backends.facebook.FacebookBackend', 'social_auth.backends.google.GoogleOAuthBackend', 'social_auth.backends.google.GoogleOAuth2Backend', 'social_auth.backends.google.GoogleBackend', 'social_auth.backends.yahoo.YahooBackend', 'social_auth.backends.browserid.BrowserIDBackend', 'social_auth.backends.contrib.linkedin.LinkedinBackend', 'social_auth.backends.contrib.livejournal.LiveJournalBackend', 'social_auth.backends.contrib.orkut.OrkutBackend', 'social_auth.backends.contrib.foursquare.FoursquareBackend', 'social_auth.backends.contrib.github.GithubBackend', 'social_auth.backends.contrib.dropbox.DropboxBackend', 'social_auth.backends.contrib.flickr.FlickrBackend', 'social_auth.backends.contrib.instagram.InstagramBackend', 'social_auth.backends.contrib.vkontakte.VKontakteBackend', 'social_auth.backends.contrib.skyrock.SkyrockBackend', 'social_auth.backends.contrib.yahoo.YahooOAuthBackend', 'social_auth.backends.OpenIDBackend', 'social_auth.backends.contrib.bitbucket.BitbucketBackend', 'social_auth.backends.contrib.mixcloud.MixcloudBackend', 'social_auth.backends.contrib.live.LiveBackend', 'django.contrib.auth.backends.ModelBackend', )
Take into account that backends must be defined in AUTHENTICATION_BACKENDS or Django won't pick them when trying to authenticate the user.
Don't miss
django.contrib.auth.backends.ModelBackend
if usingdjango.auth
user model or users won't be able to login.Setup needed OAuth keys (see OAuth section for details):
TWITTER_CONSUMER_KEY = '' TWITTER_CONSUMER_SECRET = '' FACEBOOK_APP_ID = '' FACEBOOK_API_SECRET = '' LINKEDIN_CONSUMER_KEY = '' LINKEDIN_CONSUMER_SECRET = '' ORKUT_CONSUMER_KEY = '' ORKUT_CONSUMER_SECRET = '' GOOGLE_CONSUMER_KEY = '' GOOGLE_CONSUMER_SECRET = '' GOOGLE_OAUTH2_CLIENT_ID = '' GOOGLE_OAUTH2_CLIENT_SECRET = '' FOURSQUARE_CONSUMER_KEY = '' FOURSQUARE_CONSUMER_SECRET = '' GITHUB_APP_ID = '' GITHUB_API_SECRET = '' DROPBOX_APP_ID = '' DROPBOX_API_SECRET = '' FLICKR_APP_ID = '' FLICKR_API_SECRET = '' INSTAGRAM_CLIENT_ID = '' INSTAGRAM_CLIENT_SECRET = '' VK_APP_ID = '' VK_API_SECRET = '' BITBUCKET_CONSUMER_KEY = '' BITBUCKET_CONSUMER_SECRET = '' LIVE_CLIENT_ID = '' LIVE_CLIENT_SECRET = '' SKYROCK_CONSUMER_KEY = '' SKYROCK_CONSUMER_SECRET = '' YAHOO_CONSUMER_KEY = '' YAHOO_CONSUMER_SECRET = '' MIXCLOUD_CLIENT_ID = '' MIXCLOUD_CLIENT_SECRET = ''
Setup login URLs:
LOGIN_URL = '/login-form/' LOGIN_REDIRECT_URL = '/logged-in/' LOGIN_ERROR_URL = '/login-error/'
Check Django documentation at Login URL and Login redirect URL
If a custom redirect URL is needed that must be different to
LOGIN_URL
, define the setting:SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/another-login-url/'
A different URL could be defined for newly registered users:
SOCIAL_AUTH_NEW_USER_REDIRECT_URL = '/new-users-redirect-url/'
or for newly associated accounts:
SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL = '/new-association-redirect-url/'
or for account disconnections:
SOCIAL_AUTH_DISCONNECT_REDIRECT_URL = '/account-disconnected-redirect-url/'
Users will be redirected to
LOGIN_ERROR_URL
in case of error or user cancellation on some backends. This URL can be override by this setting:SOCIAL_AUTH_BACKEND_ERROR_URL = '/new-error-url/'
Configure authentication and association complete URL names to avoid possible clashes:
SOCIAL_AUTH_COMPLETE_URL_NAME = 'socialauth_complete' SOCIAL_AUTH_ASSOCIATE_URL_NAME = 'socialauth_associate_complete'
Add URLs entries:
urlpatterns = patterns('', ... url(r'', include('social_auth.urls')), ... )
All
django-social-auth
URLs names havesocialauth_
prefix.Define context processors if needed:
TEMPLATE_CONTEXT_PROCESSORS = ( ... 'social_auth.context_processors.social_auth_by_name_backends', 'social_auth.context_processors.social_auth_backends', 'social_auth.context_processors.social_auth_by_type_backends', 'social_auth.context_processors.social_auth_login_redirect' )
social_auth_by_name_backends
: Adds asocial_auth
dict where each key is a provider name and its value is a UserSocialAuth instance if user has associated an account with that provider, otherwiseNone
.social_auth_backends
: Adds asocial_auth
dict with keys areassociated
,not_associated
andbackends
.associated
key is a list ofUserSocialAuth
instances associated with current user.not_associated
is a list of providers names that the current user doesn't have any association yet.backends
holds the list of backend names supported.social_auth_by_type_backends
: Simiar tosocial_auth_backends
but each value is grouped by backend typeopenid
,oauth2
andoauth
.social_auth_login_redirect
: For man in the middle redirects (ie authenticating via a login required decorator), a convenince query string can be added to your context for templates. On your login options page:<a href={{% url socialauth_begin 'twitter' %}?{{ redirect_querystring }}">...</a>
allows for a continuous login. Useful if multiple login options are presented.
Check
social_auth.context_processors
for details.Note:
social_auth_backends
andsocial_auth_by_type_backends
don't play nice together.Sync database to create needed models:
./manage.py syncdb
Not mandatory, but recommended:
SOCIAL_AUTH_DEFAULT_USERNAME = 'new_social_auth_user'
or:
import random SOCIAL_AUTH_DEFAULT_USERNAME = lambda: random.choice(['Darth Vader', 'Obi-Wan Kenobi', 'R2-D2', 'C-3PO', 'Yoda'])
in case your user layout needs to purify username on some weird way.
Final user name will have a random UUID-generated suffix in case it's already taken. The UUID token max length can be changed with the setting:
SOCIAL_AUTH_UUID_LENGTH = 16
Backends will store extra values from response by default, set this to False to avoid such behavior:
SOCIAL_AUTH_EXTRA_DATA = False
Also more extra values will be stored if defined, details about this setting are listed below on OpenId and OAuth sections.
The update_user_details pipeline processor will set certain fields on user objects, such as
email
. Set this to a list of fields you only want to set for newly created users:SOCIAL_AUTH_PROTECTED_USER_FIELDS = ['email',]
Session expiration time is an special value, it's recommended to define:
SOCIAL_AUTH_EXPIRATION = 'expires'
and use such setting name where expiration times are returned. View that completes login process will set session expiration time using this name if it's present or
expires
by default. Expiration configuration can be disabled with setting:SOCIAL_AUTH_SESSION_EXPIRATION = False
It's possible to override the used
User
model if needed:SOCIAL_AUTH_USER_MODEL = 'myapp.CustomUser'
This class must have a custom Model Manager with a
create_user
method that resembles the one on auth.UserManager.Also, it's highly recommended that this class define the following fields:
username = CharField(...) last_login = DateTimeField(blank=True) is_active = BooleanField(...)
and the method:
is_authenticated(): ...
These are needed to ensure a better
django-auth
integration, in other case login_required won't be usable. A warning is displayed if any of these are missing. By default auth.User is used.Check example application for implementation details, but first, please take a look to User Profiles, it might be what you were looking for.
It's possible to disable user creations by
django-social-auth
with:SOCIAL_AUTH_CREATE_USERS = False
It is also possible to associate multiple user accounts with a single email address, set value as True to enable, otherwise set as False to disable. This behavior is disabled by default (False) unless specifically set:
SOCIAL_AUTH_ASSOCIATE_BY_MAIL = True
You can send extra parameters on auth process by defining settings per provider, example to request Facebook to show Mobile authorization page, define:
FACEBOOK_AUTH_EXTRA_ARGUMENTS = {'display': 'touch'}
For other providers, just define settings in the form:
<uppercase backend name>_AUTH_EXTRA_ARGUMENTS = {...}
Also, you can send extra parameters on request token process by defining settings per provider in the same way explained above but with this other suffix:
<uppercase backend name>_REQUEST_TOKEN_EXTRA_ARGUMENTS = {...}
By default the application doesn't make redirects to different domains, to disable this behavior:
SOCIAL_AUTH_SANITIZE_REDIRECTS = False
Inactive users can be redirected to a different page if this setting is defined:
SOCIAL_AUTH_INACTIVE_USER_URL = '...'
Defaults to
LOGIN_ERROR_URL
.The application catches any exception and logs errors to
logger
ordjango.contrib.messagess
application by default. But it's possible to override the default behavior by defining a function to process the exceptions using this setting:SOCIAL_AUTH_PROCESS_EXCEPTIONS = 'social_auth.utils.process_exceptions'
The function parameters will
request
holding the current request object,backend
with the current backend anderr
which is the exception instance.Recently this set of exceptions were introduce to describe the situations a bit more than the old
ValueError
usually raised:AuthException - Base exception class AuthFailed - Authentication failed for some reason AuthCanceled - Authentication was canceled by the user AuthUnknownError - An unknown error stoped the authentication process AuthTokenError - Unauthorized or access token error, it was invalid, impossible to authenticate or user removed permissions to it. AuthMissingParameter - A needed parameter to continue the process was missing, usually raised by the services that need some POST data like myOpenID
These are a subclass of
ValueError
to keep backward compatibility.Having tracebacks is really useful when debugging, for that purpose this setting was defined:
SOCIAL_AUTH_RAISE_EXCEPTIONS = DEBUG
It's default value is
DEBUG
, so you need to set it toFalse
to avoid tracebacks whenDEBUG = True
.When your project is behind a reverse proxy that uses HTTPS the redirect URIs can became with the wrong schema (
http://
instead ofhttps://
), and might cause errors with the auth process, to force HTTPS in the final URIs define this setting:SOCIAL_AUTH_REDIRECT_IS_HTTPS = True
The name of the last backend used to login is stored as a string in the session under the key
social_auth_last_login_backend
, the key can be customized by defining this setting:SOCIAL_AUTH_LAST_LOGIN = 'social_auth_last_login_backend'
Some settings can be tweak by backend by adding the backend name prefix (all
uppercase and replace -
with _
), here's the supported settings so far:
LOGIN_ERROR_URL SOCIAL_AUTH_BACKEND_ERROR_URL SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL SOCIAL_AUTH_DISCONNECT_REDIRECT_URL SOCIAL_AUTH_NEW_USER_REDIRECT_URL SOCIAL_AUTH_LOGIN_REDIRECT_URL SOCIAL_AUTH_INACTIVE_USER_URL
The ORM models can be replaced by providing the name of an alternate module for the
SOCIAL_AUTH_MODELS
setting. The default is'social_auth.db.django_models'
, which defines the Django ORM models that were originally defined to implement Social Auth's storage. The app provides an example alternate based on MongoEngine. You can use it by setting:SOCIAL_AUTH_MODELS = 'social_auth.db.mongoengine_models'
Make sure you've followed the instructions for MongoEngine Django integration, as you're now utilizing that user model.
The MongoEngine_ backend was developed and tested with version 0.6.10 of MongoEngine_.
Alternate storage models implementations currently follow a tight pattern of models that behave near or identical to Django ORM models. It is currently not decoupled from this pattern by any abstraction layer. If you would like to implement your own alternate, please see the
social_auth.db.django_models
andsocial_auth.db.mongoengine_models
modules for guidance.
The final process of the authentication workflow is handled by a operations pipeline where custom functions can be added or default items can be removed to provide a custom behavior.
The default pipeline mimics the user creation and basic data gathering from previous django-social-auth versions and a big set of settings (listed below) that were used to alter the default behavior are now deprecated in favor of pipeline overrides.
The default pipeline is composed by:
( # Find UserSocialAuth object by backend and backend uid. # Fail if UserSocialAuth already exists but not associated with # the current user in the pipeline. Otherwise set the current user # in the pipeline to be the user associated with UserSocialAuth 'social_auth.backends.pipeline.social.social_auth_user', # Try to find an existing user that has the email address provided # by the authentication backend. Fail if email addr. is not unique 'social_auth.backends.pipeline.associate.associate_by_email', # If no user is found so far, generate a unique username based on # configured settings 'social_auth.backends.pipeline.user.get_username', # Depends on get_username. If no user is found so far, then create # a new user based on the username returned by get_username # If new user is created, set the current user in the pipeline to be # the newly created user and set the is_new arg to be true and # sends the socialauth_not_registered signal 'social_auth.backends.pipeline.user.create_user', # If no instance of UserSocialAuth is found so far (through social_auth_user) # create a new UserSocialAuth instance associated with the given user 'social_auth.backends.pipeline.social.associate_user', # Take the extra data given by backend and store them in the # UserSocialAuth instance's extra_data field, updating existing values # Depends on an instance of UserSocialAuth to exist of course 'social_auth.backends.pipeline.social.load_extra_data', # Update fields on the user object based on details provided by the # authentication backend, skipping sensative fields such as username, # id, pk, (and other provided in SOCIAL_AUTH_PROTECTED_USER_FIELDS if a # user is already registered) # Fires the pre_update signal before updating and socialauth_registered # signal if is_new flag is set (by create_user pipeline) 'social_auth.backends.pipeline.user.update_user_details' )
But it's possible to override it by defining the setting
SOCIAL_AUTH_PIPELINE
, for example a pipeline that won't create users, just
accept already registered ones would look like this:
SOCIAL_AUTH_PIPELINE = ( 'social_auth.backends.pipeline.social.social_auth_user', 'social_auth.backends.pipeline.social.associate_user', 'social_auth.backends.pipeline.social.load_extra_data', 'social_auth.backends.pipeline.user.update_user_details' )
- Each pipeline function will receive the following parameters:
- Current social authentication backend
- User ID given by authentication provider
- User details given by authentication provider
is_new
flag (initialized inFalse
)- Any arguments passed to
auth_complete
backend method, default views pass this arguments:- current logged in user (if it's logged in, otherwise
None
) - current request
- current logged in user (if it's logged in, otherwise
Each pipeline entry must return a dict
or None
, any value in the
dict
will be used in the kwargs
argument for the next pipeline entry.
The workflow will be cut if the exception
social_auth.backends.exceptions.StopPipeline
is raised at any point.
If any function returns something else beside a dict
or None
, the
workflow will be cut and the value returned immediately, this is useful to
return HttpReponse
instances like HttpResponseRedirect
.
It's possible to cut the pipeline process to return to the user asking for more
data and resume the process later, to accomplish this add the entry
social_auth.backends.pipeline.misc.save_status_to_session
(or a similar
implementation) to the pipeline setting before any entry that returns an
HttpResponse
instance:
SOCIAL_AUTH_PIPELINE = ( ... social_auth.backends.pipeline.misc.save_status_to_session, app.pipeline.redirect_to_basic_user_data_form ... )
When it's time to resume the process just redirect the user to
/complete/<backend>/
view. By default the pipeline will be resumed in the
next entry after save_status_to_session
but this can be modified by setting
the following setting to the import path of the pipeline entry to resume
processing:
SOCIAL_AUTH_PIPELINE_RESUME_ENTRY = 'social_auth.backends.pipeline.misc.save_status_to_session'
save_status_to_session
saves needed data into user session, the key can be
defined by SOCIAL_AUTH_PARTIAL_PIPELINE_KEY
which default value is
partial_pipeline
:
SOCIAL_AUTH_PARTIAL_PIPELINE_KEY = 'partial_pipeline'
Check the example application to check a basic usage.
The following settings are deprecated in favor of pipeline functions.
These settings should be avoided and override
get_username
pipeline entry with the desired behavior:SOCIAL_AUTH_FORCE_RANDOM_USERNAME SOCIAL_AUTH_DEFAULT_USERNAME SOCIAL_AUTH_UUID_LENGTH SOCIAL_AUTH_USERNAME_FIXER SOCIAL_AUTH_ASSOCIATE_URL_NAME
User creation setting should be avoided and remove the entry
create_user
from pipeline instead:SOCIAL_AUTH_CREATE_USERS
Automatic data update should be stopped by overriding
update_user_details
pipeline entry instead of using this setting:SOCIAL_AUTH_CHANGE_SIGNAL_ONLY
Extra data retrieval from providers should be stopped by removing
load_extra_data
from pipeline instead of using this setting:SOCIAL_AUTH_EXTRA_DATA
Automatic email association should be avoided by removing
associate_by_email
pipeline entry instead of using this setting:SOCIAL_AUTH_ASSOCIATE_BY_MAIL
Associate URLs are deprecated since the login ones can handle the case, this avoids issues where providers check the redirect URI and redirects to the configured value in the application. So, from now on a single entry point is recommended being:
/<social auth path>/login/<backend>/
And to complete the process:
/<social auth path>/complete/<backend>/
Authentication process starts with socialauth_begin
URL.
Template code example:
<ul> <li> <a href="{% url socialauth_begin 'twitter' %}">Enter using Twitter</a> </li> <li> <a href="{% url socialauth_begin 'facebook' %}">Enter using Facebook</a> </li> </ul>
In the example above we assume that Twitter and Facebook authentication backends enabled, and following settings provided:
TWITTER_CONSUMER_KEY = 'real key here' TWITTER_CONSUMER_SECRET = 'real secret here' FACEBOOK_APP_ID = 'real id here' FACEBOOK_API_SECRET = 'real secret here'
A pre_update
signal is sent when user data is about to be updated with new
values from authorization service provider, this apply to new users and already
existent ones. This is useful to update custom user fields or User Profiles,
for example, to store user gender, location, etc. Example:
from social_auth.signals import pre_update from social_auth.backends.facebook import FacebookBackend def facebook_extra_values(sender, user, response, details, **kwargs): user.gender = response.get('gender') return True pre_update.connect(facebook_extra_values, sender=FacebookBackend)
New data updating is made automatically but could be disabled and left only to signal handler if this setting value is set to True:
SOCIAL_AUTH_CHANGE_SIGNAL_ONLY = False
Take into account that when defining a custom User
model and declaring
signal handler in models.py
, the imports and handler definition must be
made after the custom User
model is defined or circular imports issues will
be raised.
Also a new-user signal (socialauth_registered
) is sent when new accounts
are created:
from social_auth.signals import socialauth_registered def new_users_handler(sender, user, response, details, **kwargs): user.is_new = True return False socialauth_registered.connect(new_users_handler, sender=None)
Almost every service covered provide some kind of API that is protected with
access_token
or token pairs (like Twitter OAuth keys). These tokens are
gathered by the authentication mechanism and stored in
UserSocialAuth.extra_data
.
UserSocialAuth
has a property named tokens
to easilly access this
useful values, it will return a dictionary containing the tokens values.
A simple usage example:
>>> from pprint import pprint >>> from social_auth.models import UserSocialAuth >>> instance = UserSocialAuth.objects.filter(provider='twitter').get(...) >>> pprint(instance.tokens) {u'oauth_token': u'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', u'oauth_token_secret': u'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'} >>> instance = UserSocialAuth.objects.filter(provider='facebook').get(...) >>> pprint(instance.tokens) {u'access_token': u'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'}
OpenId support is simpler to implement than OAuth. Google and Yahoo providers are supported by default, others are supported by POST method providing endpoint URL.
OpenId backends can store extra data in UserSocialAuth.extra_data
field
by defining a set of values names to retrieve from any of the used schemas,
AttributeExchange
and SimpleRegistration
. As their keywords differ we
need two settings.
Settings is per backend, so we have two possible values for each one. Name is dynamically checked using uppercase backend name as prefix:
<uppercase backend name>_SREG_EXTRA_DATA <uppercase backend name>_AX_EXTRA_DATA
Example:
GOOGLE_SREG_EXTRA_DATA = [(..., ...)] GOOGLE_AX_EXTRA_DATA = [(..., ...)]
Settings must be a list of tuples mapping value name in response and value
alias used to store. A third value (boolean) is supported to, it's purpose is
to signal if the value should be discarded if it evaluates to False
, this
is to avoid replacing old (needed) values when they don't form part of current
response. If not present, then this check is avoided and the value will replace
any data.
OAuth communication demands a set of keys exchange to validate the client authenticity prior to user approbation. Twitter, Facebook and Orkut facilitates these keys by application registration, Google works the same, but provides the option for unregistered applications.
Check next sections for details.
OAuth backends also can store extra data in UserSocialAuth.extra_data
field by defining a set of values names to retrieve from service response.
Settings is per backend and it's name is dynamically checked using uppercase backend name as prefix:
<uppercase backend name>_EXTRA_DATA
Example:
FACEBOOK_EXTRA_DATA = [(..., ...)]
Settings must be a list of tuples mapping value name in response and value
alias used to store. A third value (boolean) is supported to, it's purpose is
to signal if the value should be discarded if it evaluates to False
, this
is to avoid replacing old (needed) values when they don't form part of current
response. If not present, then this check is avoided and the value will replace
any data.
Twitter offers per application keys named Consumer Key
and Consumer
Secret
. To enable Twitter these two keys are needed. Further documentation
at Twitter development resources:
Register a new application at Twitter App Creation,
mark the "Yes, use Twitter for login" checkbox, and
fill
Consumer Key
andConsumer Secret
values:TWITTER_CONSUMER_KEY TWITTER_CONSUMER_SECRET
You need to specify an URL callback or the application will be marked as Client type instead of the Browser. Almost any dummy value will work if you plan some test.
Facebook works similar to Twitter but it's simpler to setup and redirect URL is passed as a parameter when issuing an authorization. Further documentation at Facebook development resources:
Register a new application at Facebook App Creation, and
fill
App Id
andApp Secret
values in values:FACEBOOK_APP_ID FACEBOOK_API_SECRET
Define
FACEBOOK_EXTENDED_PERMISSIONS
to get extra permissions from facebook. NOTE: to get users' email addresses, you must request the 'email' permission:FACEBOOK_EXTENDED_PERMISSIONS = ['email']
Take into account that Facebook doesn't return user email by default, this setting is needed if email is required:
FACEBOOK_EXTENDED_PERMISSIONS = ['email']
Define
FACEBOOK_PROFILE_EXTRA_PARAMS
to pass extra parameters to https://graph.facebook.com/me when gathering the user profile data, like:FACEBOOK_PROFILE_EXTRA_PARAMS = {'locale': 'ru_RU'}
If you define a redirect URL in Facebook setup page, be sure to not define http://127.0.0.1:8000 or http://localhost:8000 because it won't work when testing. Instead I define http://myapp.com and setup a mapping on /etc/hosts or use dnsmasq.
- If you need to perform authentication from Facebook Canvas application:
- Create your canvas application at http://developers.facebook.com/apps
- In Facebook application settings specify your canvas URL
mysite.com/fb
(current default) - Setup your Django Social Auth settings like you usually do for Facebook authentication (FACEBOOK_APP_ID etc)
- Launch manage.py via sudo
./manage.py runserver mysite.com:80
for browser to be able to load it when Facebook calls canvas URL - Open your Facebook page via http://apps.facebook.com/app_namespace or better via http://www.facebook.com/pages/user-name/user-id?sk=app_app-id
- After that you will see this page in a right way and will able to connect to application and login automatically after connection
More info on the topic at Facebook Canvas Application Authentication.
Orkut offers per application keys named Consumer Key
and Consumer
Secret
. To enable Orkut these two keys are needed.
Check Google support and Orkut API for details on getting your consumer_key and consumer_secret keys.
fill
Consumer Key
andConsumer Secret
values:ORKUT_CONSUMER_KEY ORKUT_CONSUMER_SECRET
add any needed extra data to:
ORKUT_EXTRA_DATA = ''
configure extra scopes in:
ORKUT_EXTRA_SCOPES = [...]
Google provides Consumer Key
and Consumer Secret
keys to registered
applications, but also allows unregistered application to use their
authorization system with, but beware that this method will display a security
banner to the user telling that the application is not trusted.
Check Google OAuth and make your choice.
fill
Consumer Key
andConsumer Secret
values:GOOGLE_CONSUMER_KEY GOOGLE_CONSUMER_SECRET
anonymous values will be used if not configured as described in their OAuth reference
configure the display name to be used in the "grant permissions" dialog that Google will display to users in:
GOOGLE_DISPLAY_NAME = ''
shows 'Social Auth' by default, but that might not suite your application.
setup any needed extra scope in:
GOOGLE_OAUTH_EXTRA_SCOPE = [...]
Check which applications can be included in their Google Data Protocol Directory
Recently Google launched OAuth2 support following the definition at OAuth2 draft. It works in a similar way to plain OAuth mechanism, but developers must register an application and apply for a set of keys. Check Google OAuth2 document for details.
- Note:
- This support is experimental as Google implementation may change and OAuth2 is still a draft.
To enable OAuth2 support:
fill
Client ID
andClient Secret
settings, these values can be obtained easily as described on OAuth2 Registering doc:GOOGLE_OAUTH2_CLIENT_ID = '' GOOGLE_OAUTH2_CLIENT_SECRET = ''
previous name
GOOGLE_OAUTH2_CLIENT_KEY
is supported for backward compatibility.scopes are shared between OAuth mechanisms:
GOOGLE_OAUTH_EXTRA_SCOPE = [...]
Check which applications can be included in their Google Data Protocol Directory
LinkedIn setup is similar to any other OAuth service. To request extra fields using LinkedIn fields selectors just define the setting:
LINKEDIN_EXTRA_FIELD_SELECTORS = [...]
with the needed fields selectors, also define LINKEDIN_EXTRA_DATA properly,
that way the values will be stored in UserSocialAuth.extra_data
field.
By default id
, first-name
and last-name
are requested and stored.
GitHub works similar to Facebook (OAuth).
Register a new application at GitHub Developers, set your site domain as the callback URL or it might cause some troubles when associating accounts,
Fill
App Id
andApp Secret
values in the settings:GITHUB_APP_ID = '' GITHUB_API_SECRET = ''
Also it's possible to define extra permissions with:
GITHUB_EXTENDED_PERMISSIONS = [...]
Bitbucket works similar to Twitter (OAuth).
Register a new application by emailing
[email protected]
with an application name and a bit of a description,Fill
Consumer Key
andConsumer Secret
values in the settings:BITBUCKET_CONSUMER_KEY = '' BITBUCKET_CONSUMER_SECRET = ''
Dropbox uses OAuth v1.0 for authentication.
Register a new application at Dropbox Developers, and
fill
App Key
andApp Secret
values in the settings:DROPBOX_APP_ID = '' DROPBOX_API_SECRET = ''
Flickr uses OAuth v1.0 for authentication.
Register a new application at the Flickr App Garden, and
fill
Key
andSecret
values in the settings:FLICKR_APP_ID = '' FLICKR_API_SECRET = ''
Flickr might show a messages saying "Oops! Flickr doesn't recognise the permission set.", if encountered with this error, just define this setting:
FLICKR_AUTH_EXTRA_ARGUMENTS = {'perms':'read'}
Support for BrowserID is possible by posting the assertion
code to
/complete/browserid/
URL.
The setup doesn't need any setting, just the usual BrowserID javascript include in your document and the needed mechanism to trigger the POST to django-social-auth.
Check the second "Use Case" for an implementation example.
Instagram uses OAuth v2 for Authentication
Register a new application at the Instagram API, and
fill
Client Id
andClient Secret
values in the settings:INSTAGRAM_CLIENT_ID = '' INSTAGRAM_CLIENT_SECRET = ''
extra scopes can be defined by using:
INSTAGRAM_AUTH_EXTRA_ARGUMENTS = {'scope': 'likes comments relationships'}
Note
Instagram only allows one callback url so you'll have to change your
urls.py to accomodate both /complete
and /associate
routes, for
example by having a single /associate
url which takes
a ?complete=true
parameter for the cases when you want to complete
rather than associate.
Vkontakte uses OAuth v2 for Authentication
Register a new application at the Vkontakte API, and
fill
App Id
andApi Secret
values in the settings:VK_APP_ID = '' VK_API_SECRET = ''
Define VK_EXTRA_DATA to pass extra fields when gathering the user profile data, like:
VK_EXTRA_DATA = ['photo','country']
Also it's possible to define extra permissions with:
VK_EXTRA_SCOPE = [...]
See the names of the privileges VKontakte.
You can also use Vkontakte's own OpenAPI to log in, but you need to provide a HTML template with JavaScript code to authenticate. See vkontakte.html in templates folder for details.
To support authentication for VKontakte applications see authentication for VKontakte applications.
OAuth2 based Live Connect workflow, notice that it isn't OAuth WRAP.
Register a new application at Live Connect Developer Center, set your site domain as redirect domain,
Fill
Client Id
andClient Secret
values in the settings:LIVE_CLIENT_ID = '' LIVE_CLIENT_SECRET = ''
Also it's possible to define extra permissions with:
LIVE_EXTENDED_PERMISSIONS = [...]
Defaults are "wl.basic" and "wl.emails". Latter one is necessary to retrieve user email.
Skyrock offers per application keys named Consumer Key
and Consumer
Secret
. To enable Skyrock these two keys are needed. Further documentation at
Skyrock API Documentation:
Register a new application at Skyrock App Creation,
fill
Consumer Key
andConsumer Secret
values:SKYROCK_CONSUMER_KEY SKYROCK_CONSUMER_SECRET
OAuth 1.0 workflow, useful if you are planning to use Yahoo's API.
Register a new application at Yahoo Developer Center, set your app domain and configure scopes (they can't be overriden by application).
Fill
Consumer Key
andConsumer Secret
values in the settings:YAHOO_CONSUMER_KEY = '' YAHOO_CONSUMER_SECRET = ''
Evernote OAuth 1.0 workflow.
Register a new application at Evernote API Key form.
Fill
Consumer Key
andConsumer Secret
values in the settings:EVERNOTE_CONSUMER_KEY = '' EVERNOTE_CONSUMER_SECRET = ''
To test in the sandbox add to settings:
EVERNOTE_DEBUG = True
Yandex uses OAuth 2.0 workflow, fill and YANDEX_APP_ID
and
YANDEX_API_SECRET
settings to log in.
Currently there are 2 backends for Yandex, one is Yaru to log in using Ya.ru
service and another one is YandexOAuth that could use service API from
settings. Use YANDEX_OAUTH2_API_URL
to set up which service to use.
Tested with 'https://api-yaru.yandex.ru/me/' for Ya.ru and 'http://api.moikrug.ru/v1/my/' for Moi Krug.
Yandex also uses OpenID 2.0. You do not need to provide user's name because Yandex will do it for you.
Mail.ru uses OAuth2 workflow, to use it fill in settings:
MAILRU_OAUTH2_CLIENT_KEY = '' MAILRU_OAUTH2_APP_KEY = '' MAILRU_OAUTH2_CLIENT_SECRET = ''
Odnoklassniki.ru uses OAuth2 workflow, to use it fill in settings:
ODNOKLASSNIKI_OAUTH2_CLIENT_KEY = '' ODNOKLASSNIKI_OAUTH2_APP_KEY = '' ODNOKLASSNIKI_OAUTH2_CLIENT_SECRET = ''
The Mixcloud API offers support for authorization. To enable OAuth2 support:
Register a new application at Mixcloud Developers
Add Mixcloud backend to
AUTHENTICATION_BACKENDS
in settings:AUTHENTICATION_BACKENDS = ( ... 'social_auth.backends.contrib.mixcloud.MixcloudBackend', )
Fill
Client Id
andClient Secret
values in the settings:MIXCLOUD_CLIENT_ID = '' MIXCLOUD_CLIENT_SECRET = ''
Similar to the other OAuth backends you can define:
MIXCLOUD_EXTRA_DATA = [('username', 'username'), ('name', 'name'), ('pictures', 'pictures'), ('url', 'url')]
as a list of tuples (response name, alias)
to store user profile data on the UserSocialAuth model.
To test the application just run:
./manage.py test social_auth
This will run a bunch of tests, so far only login process is tested, more will come eventually.
User accounts on the different sites are needed to run tests, configure the credentials in the following way:
# twitter testing TEST_TWITTER_USER = 'testing_account' TEST_TWITTER_PASSWORD = 'password_for_testing_account' # facebook testing TEST_FACEBOOK_USER = 'testing_account' TEST_FACEBOOK_PASSWORD = 'password_for_testing_account' # google testing TEST_GOOGLE_USER = '[email protected]' TEST_GOOGLE_PASSWORD = 'password_for_testing_account'
There's support for Selenium tests too on root contrib directory. To run install selenium:
$ pip install selenium
and create a test_settings.py
copying test_settings.py.template
and
fill the needed account information. Then run:
cd contrib/tests ./runtests.py
Some particular use cases are listed below.
Use social auth just for account association (no login):
urlpatterns += patterns('', url(r'^associate/(?P<backend>[^/]+)/$', associate, name='socialauth_associate_begin'), url(r'^associate/complete/(?P<backend>[^/]+)/$', associate_complete, name='socialauth_associate_complete'), url(r'^disconnect/(?P<backend>[^/]+)/$', disconnect, name='socialauth_disconnect'), url(r'^disconnect/(?P<backend>[^/]+)/(?P<association_id>[^/]+)/$', disconnect, name='socialauth_disconnect_individual'), )
Include a similar snippet in your page to make BrowserID work:
<!-- Include BrowserID JavaScript --> <script src="https://browserid.org/include.js" type="text/javascript"></script> <!-- Define a form to send the POST data --> <form method="post" action="{% url socialauth_complete "browserid" %}"> <input type="hidden" name="assertion" value="" /> <a rel="nofollow" id="browserid" href="#">BrowserID</a> </form> <!-- Setup click handler that retieves BrowserID assertion code and sends POST data --> <script type="text/javascript"> $(function () { $('#browserid').click(function (e) { e.preventDefault(); var self = $(this); navigator.id.get(function (assertion) { if (assertion) { self.parent('form') .find('input[type=hidden]') .attr('value', assertion) .end() .submit(); } else { alert('Some error occurred'); } }); }); }); </script>
Join to django-social-auth discussion list and bring any questions or suggestions that would improve this application. Convore discussion group is deprecated since the service is going to be shut down on April 1st.
South users should add this rule to enable migrations:
try: import south from south.modelsinspector import add_introspection_rules add_introspection_rules([], ["^social_auth\.fields\.JSONField"]) except: pass
If defining a custom user model, do not import social_auth
from any
models.py
that would finally import from the models.py
that defines
your User
class or it will make your project fail with a recursive import
because social_auth
uses get_model()
to retrieve your User.
There's an ongoing movement to create a list of third party backends on
djangopackages.com, so, if somebody doesn't want it's backend in the
contrib
directory but still wants to share, just split it in a separated
package and link it there.
Seems that this bug described in StackOverflow hits users using django-social-auth with Python versions 2.7.2rev4 and 2.7.3 (so far) and Facebook backend. The bug report #315 explains it a bit more and shows a workaround fit avoid it.
Maybe several, please create issues in github
Attributions to whom deserves:
- caioariede (Caio Ariede):
- Improvements and Orkut support
- krvss (Stas Kravets):
- Initial setup.py configuration
- LiveJournal support
- Mail.ru, Odnoklassniki support
- Yandex OpenID support
- VKontakte OpenAPI support
- jezdez (Jannis Leidel):
- Improvements and documentation update
- alfredo (Alfredo Ramirez)
- Facebook and Doc improvements
- mattucf (Matt Brown)
- Twitter and OAuth improvements
- Quard (Vadym Zakovinko)
- LinkedIn support
- micrypt (Seyi Ogunyemi)
- OAuth2 migration
- bedspax
- Foursquare support
- revolunet (Julien Bouquillon)
- GitHub support
- danielgtaylor (Daniel G. Taylor)
- Dropbox support
- Flickr support
- Provider name context processor
- r4vi (Ravi Kotecha)
- Instagram support
- andrusha (Andrew Korzhuev)
- MSN Live Connect support
- Yahoo OAuth 1.0 support
- niQo (Nicolas Quiénot)
- Skyrock.com support
- hassek (Tomas Henriquez)
- Evernote support
- fmoga (Florian Moga)
- Mixcloud support
- estebistec (Steven Cummings)
- Overrideable models feature
Base work is copyrighted by:
django-twitter-oauth:
Original Copyright goes to Henrik Lied (henriklied) Code borrowed from https://github.com/henriklied/django-twitter-oauth
django-openid-auth:
django-openid-auth - OpenID integration for django.contrib.auth Copyright (C) 2007 Simon Willison Copyright (C) 2008-2010 Canonical Ltd.