Авторизация через Telegram Login Widget на примере Python и Django
Принцип работы виджета Telegram
6 февраля 2018 года команда Telegram анонсировала запуск Telegram Login Widget для внешних сайтов.
Оценить возможности виджета можно по ссылке: https://testwidgetbot.herokuapp.com/
Виджет предназначен для авторизации на сайте с помощью Telegram.
Виджет представляет собой кнопку с надписью Log in with Telegram. При нажатии на эту кнопку появляется окно, в которое пользователь должен ввести свой номер телефона. Введенный номер телефона не будет сообщен администратору сайта.
После ввода номера телефона пользователю придет уведомление в Telegram от пользователя Telegram следующего содержания:
Андрей, we received a request to log in on testwidgetbot.herokuapp.com with your Telegram account.
To authorize this request, tap the 'Confirm' button below.
Browser: Firefox on Linux
IP: xx.xx.xx.xx (Russia)
If you didn't request this, tap 'Decline' or ignore this message.
Под сообщением будет две кнопки: Accept
и Decline
. При нажатии
Decline
запрос авторизации будет проигнорирован. При нажатии
Accept
запрос авторизации будет принят.
Как только пользователь примет запрос авторизации в приложении Telegram, сайт получит информацию об авторизованном пользователе.
Создание бота Telegram
Для реализации системы авторизации необходимо создать бота.
Для этого необходимо написать в Telegram боту @BotFather. Это служебный бот для создания других ботов.
Создание бота происходит путем отправки ему команды /newbot
. Бот
запросит имя создаваемого бота, как его будут видеть
пользователи. Второй вопрос предполагает ввод username создаваемого
бота, @examplebot
, t.me/examplebot
. Username бота всегда должен
заканчиваться на bot
или Bot
. Это требование Telegram. Пусть наш
созданный бот называется @TestWidgetBot
.
Если введенное имя уже занято, то будет предложено ввести другое. Если
имя свободно, то BotFather пришлет токен созданного бота. Токен
представляет собой строку вида
xxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
и предназначен для
авторизации бота.
Подключение домена
В целях безопасности Telegram требует привязать созданного бота к
доменному имени. Для этого нужно отправить боту BotFather команду
/setdomain
. Бот спросит, к какому боту относится команда (необходимо
выбрать созданного ранее бота), после чего ввести домен, к которому
будет привязан созданный бот. Например, example.com
.
Теперь можно разместить бота на любой странице example.com
.
Для корректной работы виджета авторизации необхоидимо размещать сайт
на 80 или 443. То есть, если при разработке запускается тестовый
сервер, например, http://example.com:5000/
, то виджет авторизации
работать не будет. Поддомены тоже не работают, то есть разместить
виджет на http://demo.example.com/
не получится. Несколько доменов
командой /setdomain
указать нельзя.
Возможно, эти недочеты будут устранены в дальнейшем.
Генерация кода виджета авторизации
На странице сайта example.com
, в том месте страницы, где необходимо
разместить виджет авторизации необходимо разместить виджета. Для
получения скрипта можно воспользоваться
генератором на странице
документации Telegram.
В генераторе нужно ввести следующие параметры.
Username бота, без символа
@
, напримерTestWidgetBot
.Размер виджета, Small, Medium или Large.
Выбрать тип авторизации.
При выборе Redirect to URL при успешной авторизации пользователь будет переадресован на страницу с указанным URL. Параметры авторизованного пользователя (username, chat_id, first_name, last_name и пр.) будут переданы в качестве GET-параметров. Я использую именно этот тип авторизации.
При выборе Callback параметры пользователя будут переданы в качестве аргумента JavaScript функции. Параметры представляют собой JSON-объект.
Request Access необходимо установить, если требуется, чтобы бот мог начинать диалог с пользователем.
В моем случае получился такой код:
<script async src="https://telegram.org/js/telegram-widget.js?2" data-telegram-login="TestWidgetBot" data-size="large" data-auth-url="https://testwidgetbot.herokuapp.com/register/" data-request-access="write"></script>
Сгенерированный код необходимо скопировать и вставить на странице сайта.
Обработка запроса на сервере
При подтверждении пользователем авторизации на сайте, в зависимости от выбранного параметра “тип авторизации”, либо выполнится JavaScript-функция, либо пользователь будет перенаправлен на страницу Callback URL. В качестве GET-параметров на эту страницу будут переданы данные пользователя.
Рассмортрим второй вариант.
Callback URL в моем случае
https://testwidgetbot.herokuapp.com/register/
. Telegram не требует,
чтобы этот URL совпадал частично или полностью с доменом, который
установлен /setdomain
Рассмотрим на примере. Предположим что клиент с chat_id 8951599, именем Andrey, фамилией S, авторизовался на сайте в момент времени 1518613843. Тогда после подтверждения авторизации он будет перенаправлен на URL:
https://testwidgetbot.herokuapp.com/register/?id=8951599&first_name=Andrey&last_name=S&auth_date=1518613843&hash=1678ace4c395d7adgca63f446d2aedb0fad21c935ffced6315fc524a44cb7fc7
.
Параметр hash служит для проверки данных. На странице документации приведен алгоритм, по которому следует проводить валидацию данных. Я разработал класс для проверки данных по этому алгоритму, он доступен по ссылке:
https://github.com/ansmirnov/telegram-testwidgetbot/blob/master/tgwidget/utils.py
Использовать класс следует следующим образом:
from .utils import HashCheck
secret = os.getenv('BOT_TOKEN').encode('utf-8')
if not HashCheck(request.GET, secret).check_hash():
# Hash не верен
else:
# Hash верен
Переменная окружения BOT_TOKEN должна содержать токен бота.
На странице регистрации можно сохранить данные пользователя, сохранить в сессии идентификатор пользователя. В дальнейшем если пользователь зайдет на сайт, в зависимости от установленной сессии можно произвести те или иные действия.
Заключение
В статье описан общий принцип работы авторичзации пользователя на сайте с использованием Telegram Login Widget. В статье используется технологии Python и Django, однако принцип может быть реализован с применением любых технологий, позволяющий обработать GET-запрос.
Разработан демонстрационный проект. Посмотреть результат можно по ссылке https://testwidgetbot.herokuapp.com/ исходный код проекта доступен на GitHub.