Django - Урок 036. Как добавить аутентификацию через социальные сети. ВКонтакте

django, Social

По рекомендации пользователей сайта начал добавлять авторизацию через социальные сети на сайт. Первой такой социальной сетью стала ВКонтакте, как наиболее популярная социальная сеть у пользователей моего сайта.

Django сам по себе имеет необходимый функционал по работе с протоколом OAuth 2.0, который мог используется в API ВКонтакте для авторизации пользователей на сторонних ресурсах (и не только для авторизации). Но в данном случае я не стал писать свой велосипед, используя голую поддержку OAuth в Django, а нашёл очень хорошую батарейку, которая пожалуй достаточно известна среди разработчиков сайтов на Django, которая позволила внедрить авторизацию через ВКонтакте всего за пару часов.

Эта батарейка называется Python Social Auth Django .

Давайте пошагово разберёмся, что нам нужно сделать, чтобы подключить авторизацию через ВКонтакте на сайт с Django

Шаг 1 - Установка Python Social Auth Django

Делается это одной командой в вашем виртуальном окружении через утилиту pip

pip install social-auth-app-django

В документации предлагается при конфигурировании два вариант ORM для работы системы аутентификации через социальные сети. Это классическая ОРМ Django и ОРМ MongoEngine, но так получилось, что требуемый для MongoEngine пакет устарел и немного несовместим с последними версиями Django, просто не работает, даже в документации разработчиков mongoengine висит призыв о помощи с поддержкой утилиты. Поэтому будем настраивать только для классической ОРМ.

Шаг 2 - Регистрация батарейки на вашем сайте

Прописываем приложение аутентификации в INSTALLED_APPS

INSTALLED_APPS = (
    ...
    'social_django',
    ...
)

Шаг 3 - Миграция базы данных

Вам потребуется применить изменения в структуре базы данных, поскольку данная батарейка имеет свои таблицы для работы с авторизацией пользователей.

./manage.py migrate

Далее последуем ещё одной рекомендации по настройке базы данных, если Вы, как и я, используете PostgreSQL. А именно...

При использовании PostgreSQL рекомендуется использовать встроенное поле JSONB для хранения извлеченных дополнительных_данных. Чтобы включить его, задайте настройку:

SOCIAL_AUTH_POSTGRES_JSONFIELD = True

Шаг 4 - Настройка бекендов аутентификации

Также прописываем в settings.py

AUTHENTICATION_BACKENDS = (
    'social_core.backends.vk.VKOAuth2',          # бекенд авторизации через ВКонтакте
    'django.contrib.auth.backends.ModelBackend', # бекенд классической аутентификации, чтобы работала авторизация через обычный логин и пароль
)

Обязательно включите бекенд классической аутентификации, иначе потеряете возможность зайти через логин и пароль на сайт.

Шаг 5 - Настройка процессора шаблонов

У меня за полтора года разработки данного сайта настройка TEMPLATES осталась практически нетронутой, но я добавил одну строку для этой батарейки

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'social_django.context_processors.backends', # Добавил эту строку
            ],
        },
    },
]

Шаг 6 - Настройка ключей для ВКонтакте

Здесь дана настройка секретных ключей для ВКонтакте

SOCIAL_AUTH_VK_OAUTH2_KEY = 'XXXXXXX'
SOCIAL_AUTH_VK_OAUTH2_SECRET = 'XXXXXXXXXXXXXXXXXXXX'

Чтобы их получить, нужно создать в инструментарии разработчика ВКонтакте приложение и взять ID вашего приложения и секретный ключ для него.

Регистрируем приложение

Заходим в его настройки и видим всё, что нужно

В итоге прописываем в данные переменные следующие настройки

SOCIAL_AUTH_VK_OAUTH2_KEY = 'ID приложения'
SOCIAL_AUTH_VK_OAUTH2_SECRET = 'Защищённый ключ'

Шаг 7 - Подключение маршрутов для авторизации в urls.py

Делается это так

urlpatterns = [
    ...
    path('', include('social_django.urls')),
]

Шаг 8 - Добавление ссылки на маршрут

А теперь добавим ссылочку на маршрут где-нибудь в шаблоне, чтобы запускать авторизацию через ВКонтакте

<a href="/login/vk-oauth2"><img src="/static/lvk.png" class="avatar-3" data-toggle="tooltip" title="{% trans 'Login via VKontakte' %}"></a>

Шаг 9 - Настройка редиректа при авторизации

Это необязательная настройка, которая укажет URL для перенаправления пользователя на вашем страницы после успешной авторизации. Оставим корень сайта

LOGIN_REDIRECT_URL = '/'

Там уже разберётесь, как вам лучше будет сделать

Шаг 10 - Запрос разрешений на получение доступа к email

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

SOCIAL_AUTH_VK_OAUTH2_SCOPE = ['email']

Для Django рекомендую VDS-хостинг TIMEWEB

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.
Поддержать автора Donate
  • #
  • 14 июля 2018 г. 0:17

Мне интересно что будет если в обеих сетях в авторизации одинаковый еmail. Не выведет ли ошибку ?

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

В следующей статье будет описан этот момент. Опубликую статью в понедельник.
  • #
  • 7 августа 2018 г. 0:10

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

Там можно запросить доступ к тому или иному функционалу, а вот полное использование API, как я понимаю, потребует либо дописывания функционала, или использование ещё каких-нибудь батареек

Нашёл ошибку в вашем примере

какая именно? написали бы сразу ))

ИИ

Здравствуйте, у меня такая проблема: https://ibb.co/D1Y4L7g

Не могли бы вы помочь

index/ на конце url лишний у вас.

ИИ

А для insta какую ссылку вставить? 'social:begin' instagram, instagram-oauth2 - не работают

Вы ключи-то для инстаграмма настроили?

Add instagram backend to AUTHENTICATION_SETTINGS:

AUTHENTICATION_SETTINGS = (
  ...
  'social_core.backends.instagram.InstagramOAuth2',
  ...
)

fill Client Id and Client Secret values in the settings:

SOCIAL_AUTH_INSTAGRAM_KEY = ''
SOCIAL_AUTH_INSTAGRAM_SECRET = ''

extra scopes can be defined by using:

SOCIAL_AUTH_INSTAGRAM_AUTH_EXTRA_ARGUMENTS = {'scope': 'likes comments relationships'}
ИИ

Да это все я прописал и только это я и нашел в сети, я хотел узнать название ссылки

Ну из того, что я нашёл в документации и в исходниках модуля, следует, что всё-таки instagram. То есть правильно писать так

{% url 'social:begin' 'instagram' %}

Если не работает, то причина скорее в чём-то другом. Данный url рендерится у вас на странице например?

ИИ

http://localhost:8000/account/login/login/instagram/
No module named 'Social_core' Вот что пишет, а остальные работают в этом плане

Покажите, что у вас записано в бэкендах

AUTHENTICATION_BACKENDS = (
    'social_core.backends.vk.VKOAuth2',        
    'django.contrib.auth.backends.ModelBackend',
)

Дело в том, что есть django-social-auth, а есть python-social-auth. Одно - это форк другого. Это одно и тоже по сути, только один вообще для всего, а второй специально для django заточен, но есть некоторые отличия у них, например в путях.

ИИ
AUTHENTICATION_BACKENDS = (
    'social_core.backends.vk.VKOAuth2',          
    'django.contrib.auth.backends.ModelBackend', 
    'social_core.backends.facebook.FacebookOAuth2',
    'Social_core.backends.instagram.InstagramOAuth2',
)

Насколько помню, Джанговский бэкенд для аутентификации должен быть самым последним в этом списке

AUTHENTICATION_BACKENDS = (
    'social_core.backends.vk.VKOAuth2',  
    'social_core.backends.facebook.FacebookOAuth2',
    'Social_core.backends.instagram.InstagramOAuth2',
    'django.contrib.auth.backends.ModelBackend', 
)
ИИ

У меня, честно говоря, с этим были проблемы я пока отключил его. Не могу зайти через обычные логин и пароль, выдает No module named 'Social_core'. Но и после этого также, также остается проблема с инстаграм

VP

Интересно, но вот никак не могу разобраться, как можно получить список хотя бы имён друзей пользователя?

Честно, этим не занимался, но для этого нужно добавлять дополнительные запросы на разрешение к доступу к списку друзей и т.д. Рекомендую вам обратиться к документации самого ВКонтакте.

m
  • #
  • 29 сентября 2019 г. 7:39

Добрый день! Подскажите, пожалуйста, какие урлы для вк предоставляет эта батарейка? Не совсем понимаю,какой запрос мне надо отправить, чтобы авторизоваться и так далее...

Добрый день.
В данном примере все url подключаются в корень сайта.

urlpatterns = [
    ...
    path('', include('social_django.urls')),
]

Соответственно сразу для попытки логина нужно лишь написать следующий url /login/vk-oauth2

Остальные редиректы и прочее работает автоматически. Заводится с пол пинка. Если очень интересно, какие маршруты формируются, то в режиме дебага откройте несуществующую страницу, чтобы вызвать ошибку 404 и посмотрите там, какие url добавились.

url формируются в зависимости от того, где у вас подключаются маршруту данной батарейки в вашем сайте. Поэтому их начальная часть может выглядеть как угодно, чего я точно в вашем проекте знать не могу.

m
  • #
  • 29 сентября 2019 г. 8:56

Спасибо за оперативный ответ!
Я сейчас разрабатываю приложение на андроид и параллельно пытаюсь писать сервер на джанго, поэтому запуталась, как к чему подключаться
Я правильно понимаю, что после успешной авторизации клиент должен отправить на сервер полученный токен и свой айди? И если да, то по какому адресу он должен это сделать?

Если честно то с авторизацией в мобильном приложении я не работал. Знаю, что для таких вещей используют батарейку Django Rest Framework, с помощью которого можно получить токена для самого сайта, чтобы идентифицировать пользователя приложения, и через него всё ходит. Но подробный процесс я не знаю, мобильными приложениями в этом ключе совсем не занимался.

КК

Привет!!! Вопрос такой. Чтобы включить PostgreSQL, задайте настройку: SOCIAL_AUTH_POSTGRES_JSONFIELD = True. Сам вопрос: Где именно прописать или включить эту строчку???

КК

Шаг 6 - Настройка ключей для ВКонтакте Где прописать вот эти строки SOCIAL_AUTH_VK_OAUTH2_KEY = 'XXXXXXX'
SOCIAL_AUTH_VK_OAUTH2_SECRET = 'XXXXXXXXXXXXXXXXXXXX'
Я так понимаю в в settings.py ???

КК

Шаг 8 - Добавление ссылки на маршрут
А теперь добавим ссылочку на маршрут где-нибудь в шаблоне, чтобы запускать авторизацию через ВКонтакте ---- (

<a href="/login/vk-oauth2"><img src="/static/lvk.png" class="avatar-3" data-toggle="tooltip" title="{% trans 'Login via VKontakte' %}"></a>

) В шаблоне самого сайта прописать это или страницы с аутентификацией ???

Добрый день.

1) В settings.py
2) Да, в settings.py
3) Где хотите, можете где-то в шаблоне, если вам нужна авторизация с любой страницы, либо только на странице аутентификации.

КК

Спасибо!!! Буду пробовать)

КК

После написания строчки SOCIAL_AUTH_POSTGRES_JSONFIELD = True появляется ошибка при создании локального сервера. from psycopg2.extras import DateRange, DateTimeTZRange, NumericRange
ModuleNotFoundError: No module named 'psycopg2'

КК

Можно вообще проверить работоспособность на локальном джанго сервере?

Я так понимаю, вы используете пока на development машине SQLite базу данных, иначе у вас не возникло бы ни ошибки, ни вопросов по поводу этой ошибки.

Пакет устанавливается так

sudo pip install psycopg2 

Но для его использования и вообще использования данного функционала вам нужна база данных PostgreSQL, так что поднимайте на локальной машине базу данных.

Вот статья по развёртыванию Django с PostgreSQL , на локальной машине вам из той статьи будет самым интересным разделы с базой данных.

Что касается тестирования на локальной машине, то скорее всего нет. Поскольку VK должен делать правильный редирект и локальный сервер должен отвечать на внешний запрос. Полагаю, что у вас нет статического IP и редиректа до локального сервера. Так что проверить это можно в данном случае только на боевом сервере.

КК

А тут можно ссылки на сторонний ресурс показывать? Нашёл на habr похожую статью, только там чуток отличается код и про локальный сервер написано, нужно чтоб кто то понимающий посмотрел и своё мнение высказал.

Если это не чистой воды спам, а по делу, то без проблем. Но в таком случае лучше создавайте отдельный вопрос на форуме . При создании вопроса есть поле, в котором можно указать статью, которая опубликована здесь, а в тексте вопроса уже ссылку на статью и развёрнутый вопрос, что вам там не ясно.

АМ

{"error":"invalid_request","error_description":"redirect_uri has wrong domain, check application settings"} выводит такую ошибку

А что в настройках вашего приложения?
В ошибке написано, что у вас неправильные настройки домена и написано проверить настройки приложения.

A.

Читаю документацию по python-social-auth, пытаюсь понять как сохранить access_token в отдельном поле пользователя, чтобы потом иметь доступ к нему. Кто-нибудь знает как это сделать?) (access_token сохраняется после логина в поле extra_data)

Yk
<a href="/login/vk-oauth2"><img src="/static/lvk.png" class="avatar-3" data-toggle="tooltip" title="{% trans 'Login via VKontakte' %}"></a>

Выкидывает исключение в шаблоне: Invalid block tag on line 16: 'trans'. Did you forget to register or load this tag?
Новичок, поэтому не понимаю, что здесь происходит. Если это получится исправить, то как затем реализовать log out со страницы?

Не подключили в шаблоне тег локализации

{% load trans from i18n %}

log out делается через url logout`а

views.py

@login_required
def logout(request):
    auth.logout(request)
    return redirect(get_next_url(request))

urls.py

# -*- coding: utf-8 -*-

from django.urls import path

from accounts import views

app_name = 'accounts'
urlpatterns = [
    # Другие url
    path('logout/', views.logout, name='logout'),
    # Другие url
]
Yk

Когда мы нажимаем на картинку, нас должно перенаправить на окно ввода для аутентификации. Но так как ничего не происходило, добавил шаблон и прикрутил что-то подобное, ожидая чуда, увы. Page not found

def login(request):
    auth.login(request)
    return render(request, "index.html")


path('login/', views.login, name='login'),

UPD: Вообщем, программирование не мое, впустую потраченные нервы

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
Donate

Здравствуйте, уважаемые пользователи EVILEG !!!

Если сайт вам помог, то поддержите разработку сайта финансово, пожалуйста.

Вы можете сделать это следующими способами:

Спасибо, Евгений Легоцкой

АТ
10 декабря 2019 г. 8:06
Анастасия Трощенкова

C++ - Тест 001. Первая программа и типы данных

  • Результат:60баллов,
  • Очки рейтинга-1
АТ
10 декабря 2019 г. 8:02
Анастасия Трощенкова

Qt - Тест 001. Сигналы и слоты

  • Результат:73баллов,
  • Очки рейтинга1
g
10 декабря 2019 г. 4:51
gisLu

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:40баллов,
  • Очки рейтинга-8
Последние комментарии
9 декабря 2019 г. 3:41
Евгений Легоцкой

Эта ошибка invalid use of incomplete type ‘class Ui::AnotherWindow’ обычно говорит о том, что не найдено определение класса или структуры. Типичная проблема - не подключён заголовочны…
НБ
9 декабря 2019 г. 3:36
Николай Батманов

Ну, не настолько со мной всё полхо...))) Вроде бы. Я ж кнопки отрисовываю.
9 декабря 2019 г. 3:14
Евгений Легоцкой

Добрый день. У вас ui файлов по ходу нет. UI файлы используются для вёрстки в графическом дизайнере.
НБ
9 декабря 2019 г. 3:05
Николай Батманов

Здравствуйте! Полностью скопировал ваш пример к себе, чтобы разобраться. А он не хочет запускаться, дает ошибку: invalid use of incomplete type ‘class Ui::AnotherWindow’ ui(new Ui…
8 декабря 2019 г. 7:23
Евгений Легоцкой

У меня здесь есть одна старая статья с примером векторного редактора. Там есть ответы на ваши вопросы. Поизучайте Qt/C++ - Урок 072. Пример векторного редактора на Qt QGraphicsItem, QG…
Сейчас обсуждают на форуме
MU
11 декабря 2019 г. 8:27
Maciej Urmański

Thank you! Now works, and this is solution. num_embed = Embed.objects.filter(added_by=recipe.added_by).count()
11 декабря 2019 г. 8:12
Михаиллл

Так работает. Взял этот пример https://api-2d3d-cad.com/face_recognition_with_opencv/ void MainWindow::on_pushButton_4_clicked() //фото определение лица{ // Load Face cascade (.xml…
ТД
10 декабря 2019 г. 4:14
Тимур Досов

Спасибо, работает. А ещё вопрос: как загрузить страницу с динамической подгрузкой контента по скроллингу? Например - [https://ntvplus.ru/tv/]. Пока делаю через костыль - QApplication::s…
9 декабря 2019 г. 7:16
qml_puthon_user

Я сделал простой вывод текста по испусканию сигнала... Чего не хватает программе?) Python: # системные библиотекиimport cv2import numpy as npimport sysimport threading# PyQt б…
СК
8 декабря 2019 г. 16:11
Семен Косандяк

інтерфейс qt, приклад того додаю на малюнку, я натискаю на кнопку і у мене з'являється 2 текст лайну в які я вводжу значення, тобто в 1 цифри,у другому випадку це літери, тобто c++, без графічно…
EVILEG
О нас
Услуги
© EVILEG 2015-2019
Рекомендует хостинг TIMEWEB