Django 1.8. Авторизация через социальные сети с помощью django-social-auth

Авторизация на сайтах через социальные сети очень удобна, не надо заполнять регистрационные формы и т.д., вам достаточно нажать на соответствующую кнопку и вас авторизует сам сайт, при этом нужные данные он сможет получить с сайта источника (той социальной сети, с которой выполняется авторизация).

На своих проектах я использую клёвую библиотеку django-social-auth, до неё пробовал django-ulogin, но сам сервис uLogin мне не понравился (мои сумбурные заметки об этом). На пыхе также обсуждали другие библиотеки, в частности loginza, но отзывы о ней плохие, поэтому даже не пробовал. В любом случае сервисы — это сервисы, и зависимость от сервисов это больше проблема (частые падения сервисов, убогие виджеты и внешний вид без кастомизаций и т.п.) чем зависимость от библиотеки, которая проксирует запросы к конечным «социальным сетям».

Далее будем обсуждать только django-social-auth.

Вообще, нам интересно два репозитория:

  • Основной, от omab;
  • И второй, со свежой поддержкой русских социалок от krvss, в который я пулял фиксы.

Регистрации в сетях

Для начала нам надо получить ключи от необходимых социальных сетей, на странице проекта в GitHub есть инструкции для множества социальных сетей, но в свое время у меня были трудности и я решил записать последовательность действий для некоторых из них.

Facebook

Зайдите на https://developers.facebook.com/apps/ и нажмите на + Create New App. Введите название приложения (название сайта или проекта), после сабмита формы вы увидите реквизиты «App ID» и «App Secret».

Добавьте их в свой settings.py, пример:

FACEBOOK_APP_ID = '696381432507483'
FACEBOOK_API_SECRET = '15afb0bbeb173aae12e8e875ffccc7a4'

Теперь заполните поле «App Domains», укажите через пробел домены (например один локальный, другой продакшен домен). Поставьте галочку на «Website with Facebook Login» и введите адрес для редиректа, я редиректю в корень продакшен сайта.

Twitter

Зайдите на https://dev.twitter.com/ и введите логин и пароль от вашей учетной записи в Twitter. Далее заходите на https://dev.twitter.com/apps и жмёте на Create a new application, заполните нужные поля и соглашаетесь с правилами, после чего вы получите «Consumer key» и «Consumer secret».

Добавьте их в settings.py, пример:

TWITTER_CONSUMER_KEY = 'G2wMq4KYpTmgZDcjg0EzQ'
TWITTER_CONSUMER_SECRET = 'rGHMGIbOwIEpoxjXzOahc2KmvxY8h10DpZ90LwqEjec'

По умолчанию вам выдадут Access level «Read-only», для авторизации этого вам хватит. Рекомендую прочитать The Application Permission Model.

Вконтакте

Зайдите на страницу https://vk.com/developers.php и нажмите Создать приложение, выберите Тип «Веб-сайт» и введите адрес сайта и имя домена. В ответ получите «ID приложения» и «Защищенный ключ».

Добавьте их в settings.py, пример:

VK_APP_ID = '1234567'
VKONTAKTE_APP_ID = VK_APP_ID
VK_API_SECRET = 'Q0owlQESOXRYd2lcgnLa'
VKONTAKTE_APP_SECRET = VK_API_SECRET

Для чего дублировать переменные, я спрашивал в блоге автора и получил ответ. Также смотрите документацию по бекенду.

Google+

Зайдите на страницу https://code.google.com/apis/console/ , нажмите Create, введите требуемые данные и во вкладке API Access увидите «Client ID» и «Client secret».

Добавьте их в settings.py, пример:

GOOGLE_OAUTH2_CLIENT_ID = '123456789.apps.googleusercontent.com'
GOOGLE_OAUTH2_CLIENT_SECRET = 'p0dJSDjs-dAJsdSAdaSDadasdrt'

GitHub

Зайдите на страницу https://github.com/settings/applications/new и введите логин и пароль от вашей учетной записи в GitHub. Введите имя приложения, адреса сайта для «URL» и «Callback URL» (у меня это один адрес корневой страницы сайта). И получите «Client ID» и «Client Secret», после чего добавьте их в settings.py:

GITHUB_APP_ID = 'da3bad06987041629b96'
GITHUB_API_SECRET = '8bb53dd4a0b1bbc12f77e147c11d5fd6082adb8d'

Теперь перейдем к настройке social_auth.

Установка и настройка django-social-auth

Для начала установим приложение:

pip install django-social-auth

Теперь отредактируйте settings.py:

# Добавляем в AUTHENTICATION_BACKENDS нужные бекенды,
# смотрите полный список https://github.com/omab/django-social-auth/blob/master/doc/configuration.rst
AUTHENTICATION_BACKENDS = (
    'social_auth.backends.twitter.TwitterBackend',
    'social_auth.backends.facebook.FacebookBackend',
    'social_auth.backends.contrib.vk.VKOAuth2Backend',
    'social_auth.backends.google.GoogleOAuth2Backend',
    'social_auth.backends.contrib.github.GithubBackend',
    'django.contrib.auth.backends.ModelBackend',
)

# Добавляем в TEMPLATE_CONTEXT_PROCESSORS процессор "social_auth_by_name_backends"
TEMPLATE_CONTEXT_PROCESSORS = (
    'django.contrib.auth.context_processors.auth',
    'django.core.context_processors.request',
    'social_auth.context_processors.social_auth_by_name_backends',
)

# И добавляем "social_auth" в INSTALLED_APPS
INSTALLED_APPS = (
    ...
    'social_auth',
)

Дополнительные настройки social_auth, добавьте в settings.py:

import random
# Если имя не удалось получить, то можно его сгенерировать
SOCIAL_AUTH_DEFAULT_USERNAME = lambda: random.choice(['Darth_Vader', 'Obi-Wan_Kenobi', 'R2-D2', 'C-3PO', 'Yoda'])
# Разрешаем создавать пользователей через social_auth
SOCIAL_AUTH_CREATE_USERS = True

# Перечислим pipeline, которые последовательно буду обрабатывать респонс 
SOCIAL_AUTH_PIPELINE = (
    # Получает по backend и uid инстансы social_user и user
    'social_auth.backends.pipeline.social.social_auth_user',
    # Получает по user.email инстанс пользователя и заменяет собой тот, который получили выше.
    # Кстати, email выдает только Facebook и GitHub, а Vkontakte и Twitter не выдают
    'social_auth.backends.pipeline.associate.associate_by_email',
    # Пытается собрать правильный username, на основе уже имеющихся данных
    'social_auth.backends.pipeline.user.get_username',
    # Создает нового пользователя, если такого еще нет
    'social_auth.backends.pipeline.user.create_user',
    # Пытается связать аккаунты
    'social_auth.backends.pipeline.social.associate_user',
    # Получает и обновляет social_user.extra_data
    'social_auth.backends.pipeline.social.load_extra_data',
    # Обновляет инстанс user дополнительными данными с бекенда
    'social_auth.backends.pipeline.user.update_user_details'
)

Подключите роуты в urls.py:

urlpatterns = patterns('',
    ...
    url(r'', include('social_auth.urls')),
)

Синхронизация БД:

./manage.py syncdb
./manage.py migrate social_auth

Документацию можно посмотреть тут:

Виджет для вывода кнопочек

Это просто шаблонный inclusion-тег, который выводит ссылочки в виде кнопочек-логотипов социальных сетей

Сам виджет я не стал публиковать в PyPI, так как не считаю это важным, вам следует просто скопировать исходники отсюда https://github.com/adw0rd/django-social-auth-widget

После чего добавьте в settings.py следующий список:

SOCIAL_AUTH_PROVIDERS = [
    {'id': p[0], 'name': p[1], 'position': {'width': p[2][0], 'height': p[2][1], }}
    for p in (
        ('github', u'Login via GitHub', (0, -70)),
        ('facebook', u'Login via Facebook', (0, 0)),
        ('twitter', u'Login via Twitter', (0, -35)),
    )
]

В вашем шаблоне с формой авторизации использовать так:

{% load social_auth_widget %}

<form action="" method="post">
    <input name="username" />
    <input name="password" />
    <input type="submit" value="Sign in" />
    {% social_auth_widget %}
</form>

Обновление аватарок при авторизации

В статье Django Social Auth: now with images имеется пример как через сигналы обновлять аватарку пользователю, на мой вгляд, код служит только для примера.

Источник: https://adw0rd.com/

Добавить комментарий