- 1. Шаг 1 - Установка Python Social Auth Django
- 2. Шаг 2 - Регистрация батарейки на вашем сайте
- 3. Шаг 3 - Миграция базы данных
- 4. Шаг 4 - Настройка бекендов аутентификации
- 5. Шаг 5 - Настройка процессора шаблонов
- 6. Шаг 6 - Настройка ключей для ВКонтакте
- 7. Шаг 7 - Подключение маршрутов для авторизации в urls.py
- 8. Шаг 8 - Добавление ссылки на маршрут
- 9. Шаг 9 - Настройка редиректа при авторизации
- 10. Шаг 10 - Запрос разрешений на получение доступа к email
По рекомендации пользователей сайта начал добавлять авторизацию через социальные сети на сайт. Первой такой социальной сетью стала ВКонтакте, как наиболее популярная социальная сеть у пользователей моего сайта.
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
Мне интересно что будет если в обеих сетях в авторизации одинаковый еmail. Не выведет ли ошибку ?
Не, не будет, в данной батарейке уже есть необходимый функционал по разрулированию этой проблемы. Аутентификации из разных социальных сетей будут сливаться на один аккаунт. Так что всё нормально должно быть.
интересно можно ли через эту батарейку получить данные на данные в вк(друзья, фото итд)
Там можно запросить доступ к тому или иному функционалу, а вот полное использование API, как я понимаю, потребует либо дописывания функционала, или использование ещё каких-нибудь батареек
Нашёл ошибку в вашем примере
какая именно? написали бы сразу ))
Здравствуйте, у меня такая проблема: https://ibb.co/D1Y4L7g
Не могли бы вы помочь
index/ на конце url лишний у вас.
А для insta какую ссылку вставить? 'social:begin' instagram, instagram-oauth2 - не работают
Вы ключи-то для инстаграмма настроили?
Add instagram backend to AUTHENTICATION_SETTINGS:
fill Client Id and Client Secret values in the settings:
extra scopes can be defined by using:
Да это все я прописал и только это я и нашел в сети, я хотел узнать название ссылки
Ну из того, что я нашёл в документации и в исходниках модуля, следует, что всё-таки instagram. То есть правильно писать так
Если не работает, то причина скорее в чём-то другом. Данный url рендерится у вас на странице например?
http://localhost:8000/account/login/login/instagram/
No module named 'Social_core' Вот что пишет, а остальные работают в этом плане
Покажите, что у вас записано в бэкендах
Дело в том, что есть django-social-auth, а есть python-social-auth. Одно - это форк другого. Это одно и тоже по сути, только один вообще для всего, а второй специально для django заточен, но есть некоторые отличия у них, например в путях.
Насколько помню, Джанговский бэкенд для аутентификации должен быть самым последним в этом списке
У меня, честно говоря, с этим были проблемы я пока отключил его. Не могу зайти через обычные логин и пароль, выдает No module named 'Social_core'. Но и после этого также, также остается проблема с инстаграм
Интересно, но вот никак не могу разобраться, как можно получить список хотя бы имён друзей пользователя?
Честно, этим не занимался, но для этого нужно добавлять дополнительные запросы на разрешение к доступу к списку друзей и т.д. Рекомендую вам обратиться к документации самого ВКонтакте.
Добрый день! Подскажите, пожалуйста, какие урлы для вк предоставляет эта батарейка? Не совсем понимаю,какой запрос мне надо отправить, чтобы авторизоваться и так далее...
Добрый день.
В данном примере все url подключаются в корень сайта.
Соответственно сразу для попытки логина нужно лишь написать следующий url /login/vk-oauth2
Остальные редиректы и прочее работает автоматически. Заводится с пол пинка. Если очень интересно, какие маршруты формируются, то в режиме дебага откройте несуществующую страницу, чтобы вызвать ошибку 404 и посмотрите там, какие url добавились.
url формируются в зависимости от того, где у вас подключаются маршруту данной батарейки в вашем сайте. Поэтому их начальная часть может выглядеть как угодно, чего я точно в вашем проекте знать не могу.
Спасибо за оперативный ответ!
Я сейчас разрабатываю приложение на андроид и параллельно пытаюсь писать сервер на джанго, поэтому запуталась, как к чему подключаться
Я правильно понимаю, что после успешной авторизации клиент должен отправить на сервер полученный токен и свой айди? И если да, то по какому адресу он должен это сделать?
Если честно то с авторизацией в мобильном приложении я не работал. Знаю, что для таких вещей используют батарейку 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 - Добавление ссылки на маршрут
А теперь добавим ссылочку на маршрут где-нибудь в шаблоне, чтобы запускать авторизацию через ВКонтакте ---- (
) В шаблоне самого сайта прописать это или страницы с аутентификацией ???
Добрый день.
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 базу данных, иначе у вас не возникло бы ни ошибки, ни вопросов по поводу этой ошибки.
Пакет устанавливается так
Но для его использования и вообще использования данного функционала вам нужна база данных PostgreSQL, так что поднимайте на локальной машине базу данных.
Вот статья по развёртыванию Django с PostgreSQL , на локальной машине вам из той статьи будет самым интересным разделы с базой данных.
Что касается тестирования на локальной машине, то скорее всего нет. Поскольку VK должен делать правильный редирект и локальный сервер должен отвечать на внешний запрос. Полагаю, что у вас нет статического IP и редиректа до локального сервера. Так что проверить это можно в данном случае только на боевом сервере.
А тут можно ссылки на сторонний ресурс показывать? Нашёл на habr похожую статью, только там чуток отличается код и про локальный сервер написано, нужно чтоб кто то понимающий посмотрел и своё мнение высказал.
Если это не чистой воды спам, а по делу, то без проблем. Но в таком случае лучше создавайте отдельный вопрос на форуме . При создании вопроса есть поле, в котором можно указать статью, которая опубликована здесь, а в тексте вопроса уже ссылку на статью и развёрнутый вопрос, что вам там не ясно.
{"error":"invalid_request","error_description":"redirect_uri has wrong domain, check application settings"} выводит такую ошибку
А что в настройках вашего приложения?
В ошибке написано, что у вас неправильные настройки домена и написано проверить настройки приложения.
Читаю документацию по python-social-auth, пытаюсь понять как сохранить access_token в отдельном поле пользователя, чтобы потом иметь доступ к нему. Кто-нибудь знает как это сделать?) (access_token сохраняется после логина в поле extra_data)
Выкидывает исключение в шаблоне: Invalid block tag on line 16: 'trans'. Did you forget to register or load this tag?
Новичок, поэтому не понимаю, что здесь происходит. Если это получится исправить, то как затем реализовать log out со страницы?
Не подключили в шаблоне тег локализации
log out делается через url logout`а
views.py
urls.py
Когда мы нажимаем на картинку, нас должно перенаправить на окно ввода для аутентификации. Но так как ничего не происходило, добавил шаблон и прикрутил что-то подобное, ожидая чуда, увы. Page not found
UPD: Вообщем, программирование не мое, впустую потраченные нервы
Есть профиль пользователя, в нем вывожу image, username, email.
Ребята и админ, подскажите пж как добавить(обновлять) image в профиль при авторизации в вк:
Uername,email при авторизации получает отлично, а вот как image обновлять - не получается.
Модель User (model.py):
В шаблоне фото профиля вывожу:
Тут скорее вопрос в том, чтобы правильно настроить бэкенд авторизации, а не к самой модели данных профиля.
Вы на своей практике выводили img от пользователя при авторизии через соц. сеть?) мнеб пример хоть посмотреть
Честно, не доводилось )))
Мысли были, но нет. Но вообще, там нужно запрашивать права доступа на изображение через OAuth, по идее фотография туда же относится. Для этого нужно настраивать соответственно бэкенд аутентификации. Также нужно правильная обработка запрос изображения.
Полагаю, что его копировать нужно будет с социальной сети на сайт.
Если заморочусь с этим, то пожалуй, напишу статью
Будет интересно, потому что на просторах рунета нет такой статьи
Подскажите пожалуйста, сделал функцию (функция не входит в class Profile, просто отдельная):
models.py #путь users/models.py
Функция получает url адрес изображения при авторизации. Выводит в консоль url. Пример URL:
Работает. НО!
Как мне получить/вывести это в шаблоне???
почему-то не работает. Модели user.avatar у меня нет. Может быть в синтаксесе ошибся? Нид хелп
Наверное, было бы лучше, если бы вы создали отдельное обсуждение на форуме )))
Но у меня вот вопрос, а вы как-то модифицировали саму модель пользователя? Просто у вас есть модель профиля, но кода модели пользователя я не вижу.
А поля avatar в модели пользователя не существует. Так что метод save ничего не сохраняет, по крайней мере в рамках того, что я увидел в вашем коде.
Никак не модифицировал, есть только class Profile
Может быть можно как-то добавить поле avatar к классу profile?
Как создать модель пользователя? Может быть можно изменить функцию, которая будет обновлять profile, с полем avatar
Короче я запутался)
Создал обсуждение: https://evileg.com/ru/forum/topic/1321/
Понятно. После работы отпишусь в том обсуждении. У меня модель пользователя переопределена.
Но можете добавить avtar и модели profile, у меня изначально много было сделано через profile, но в связи с выводом части кода в open source я перешёл на переопределение модели пользователя.
Ок, ответил в том обсуждении, добавил поле avatar в Profile, теперь не знаю как это в функции отобразить)
А в чем заключается преимущество её переопределении, зачем её переопределять?
Удобство, организация структуры базы данных. Мне лично проще добавить некоторые методы в модель User, чтобы напрямую их вызывать в шаблонах, чем городить огород из шаблонных тегов.
Как будет время, можете показать пример как можно предопределить модель User?)
Можете почитать об этом в этой статье Django - Урок 052. Переопределение модели пользователя
Выскочила ошибка при клике на регистрацию:
шаблон:
Сори забыл включить виртуальное окружение)
Здравствуйте! После клика на ссылку авторизации выдает json словарь с ошибкой:
{"error":"invalid_request","error_description":"redirect_uri is incorrect, check application redirect uri in the settings page"}
где искать ошибку?
Неправильно прописали URL, на который возвращается ответ от OAuth ВКонтакте.
Настраивайте ваше приложение в консоли разработчика ВКонтакте
Евгений, а данныя батарейка поддерживает возможность, привязать ВК и т.д. уже после прохождения регистрации?
Возможно, автор прочитает. Делал авторизацию с помощью ВК по книге Дронова. Выдает ошибку "Backend not found". Стал гуглить, нашел вашу статью, вроде почти то же самое (оно и понятно, документация-то одна и та же), но есть и отличия. Поправил как у вас, всё равно не работает.
Понимаю, что это либо что-то с бекендами, либо с urls.py.
У меня вот так:
Вопрос 1, дурацкий)) Почему не работает?
Вопрос 2. У вас urls уровня приложения или проекта? У меня не работает ни так, ни так.
Если email совпадает с тем, что в ВК, то автоматически привязывает. Если нет, то создаёт новый аккаунт.
У меня urls на уровне приложения и записаны сейчас так
после того как дам разрешение для просмотра моего емайл, вот такая ошибка:
AuthForbidden at /social-auth/complete/vk-oauth2/
Your credentials aren't allowed
Вот сетингс:
SOCIAL_AUTH_VK_OAUTH2_KEY = 'блабла'
SOCIAL_AUTH_VK_OAUTH2_SECRET = 'кей и сикрет точно введены'
SOCIAL_AUTH_VK_OAUTH2_SCOPE = ['email']
LOGIN_REDIRECT_URL = '/'
Может быть домен не разрешен в самом приложении. Иногда бывает случайно происходит и пропадает через некоторое время - какие-то неполадки со стороны соц сетей
Евгение не знаете как исправить ошибку при авторизации через вк пишет Invalid request: versions below 5.81 are deprecated. Version param should be passed as "v".
Добавь в setting.py строку: SOCIAL_AUTH_VK_OAUTH2_API_VERSION = '5.81'
Доброго времени суток, вроде все прописал, подключил, но после того как нажал кнопочку "Разрешить" при редиректе выпадает вот что :
ModuleNotFoundError at /complete/vk-oauth2/
No module named 'social'
Исключение возникает здесь :venv/lib/python3.8/site-packages/social_core/utils.py, line 52, in import_module
Подскажите как исправить. Заранее спасибо.
Получаю ошибку:
InvalidURL at /complete/vk-oauth2/
/complete/vk-oauth2/?redirect_state=
&state=
Failed to parse: https://oauth.vk.com/access_token
Request Method: GET
Request URL: http://
Django Version: 4.0.4
Exception Type: InvalidURL
Exception Value:
Failed to parse: https://oauth.vk.com/access_token
Exception Location: /usr/local/lib/python3.8/dist-packages/requests/models.py, line 384, in prepare_url
Python Executable: /usr/bin/python3
Python Version: 3.8.10
Python Path:
['/root/web',
'/usr/lib/python38.zip',
'/usr/lib/python3.8',
'/usr/lib/python3.8/lib-dynload',
'/root/.local/lib/python3.8/site-packages',
'/usr/local/lib/python3.8/dist-packages',
'/usr/lib/python3/dist-packages']
Server time: Thu, 05 May 2022 09:57:44 +0000
и совершенно не понимаю, в чём может быть проблема