Авторизация через Telegram бота
Авторизация через Telegram бота. Передача параметров пользователя из Telegram.
Al-Sher
Всем привет. Давно ничего не писал, так как не было никаких идей, но недавно, 31 мая 2019 года, Telegram выпустил новое обновление, в котором добавил новый тип данных - LoginUrl. Итак, попробую объяснить идею авторизации с помощью Telegram бота. Для начала, чтобы бот мог писать пользователю, пользователь должен отправить сообщение /start. Бот может как угодно ответить на это сообщение, например обычным приветствием или набором кнопок для взаимодействия с ботом. Именно кнопками мы и будем пользоваться для авторизации, но об этом чуть позже. Пользователь жмет на нашу кнопку, после чего перед ним появляется окошко с подтверждением действия. Если пользователь подтверждает свое действие, то он переходит на указанный в параметрах url с данными своего аккаунта, в том числе и уникальный id для пользователя.
Начнем. Для начала необходимо написать боту @BotFather для создания нашего бота. Ответив на несколько вопросов мы получим токен, с помощью которого можно управлять ботом. Далее нам необходимо добавить сайт для бота. Для этого пишем @BotFather сообщение /setdomain. Там нас спрашивают какому боту мы хотим указать url, выбираем нужного и указываем необходимый домен. Следующим шагом необходимо настроить получение сообщений ботом от пользователя. Этот шаг я описывать не буду, лишь скажу что Telegram поддерживает как ручную проверку обновлений (метод getUpdates), так и установку Webhook(метод setWebhook). Ну и конечно же нам необходимо отправлять сообщение пользователю с помощью метода sendMessage. Вот на нем я и остановлюсь подробнее. Данный метод принимает следующие параметры:
- chat_id - в данном случае id пользователю, которому мы отправляем сообщение. Получаем от Telegram в методе getUpdates или с помощью Webhook.
- text - текст сообщения. В данном случае он нам не нужен, так как мы будем использовать кнопку. Но если хотите объясниться перед пользователем, то это идеальный момент.
- parse_mode - Указывает формат отправляемого сообщения. Поддерживаются Markdown и HTML.
- disable_web_page_preview - Отключает превью для ссылки в данном сообщении.
- disable_notification - Отправка сообщение без уведомления для юзера.
- reply_to_message_id - Указывает на id сообщения, которое мы цитируем.
- reply_markup - Добавляет кнопки.
Как можно было догадаться, нам необходимы chat_id и reply_markup. reply_markup принимает параметры в виде json массива с указанием типа кнопок и их параметров. Мы будем использовать inline_keyboard, так как они поддерживают LoginUrl. Ну давайте создадим простую кнопку:
$keyboard = Array(
'inline_keyboard' => [
[
['text' => 'Нажми меня', 'login_url' => [
'url' => 'https://web-wost.ru'
]
]
]
]
);
Не забываем перевести данную кнопку в json:
$keyboard_json = json_encode($keyboard);
Ну и отправляем:
file_get_contents('https://api.telegram.org/bot' . $token . '/sendMessage?chat_id=' . $id . 'reply_markup=' . $keyboard_json);
Не забываем так же создать переменные $token с токеном бота и $id с указанием id пользователя. Если всё сделано верно, то после выполнения данного php скрипта, бот отправит пользователю сообщение с кнопкой 'Нажми меня'. После нажатия на кнопку, пользователя спросят разрешение об отправке данных и переходе по ссылке. Получаем данные от пользователя с помощью REQUEST:
$user_id = $_REQUEST['id'];
$username = $_REQUEST['username'];
$hash = $_REQUEST['hash'];
В принципе так мы получаем необходимые данные о пользователе, но их можно легко подменить. Для безопасности передачи данных Telegram отправляет нам hash. Для его проверки воспользуемся следующим кодом:
$data = $_REQUEST;
$hash = $data['hash'];
unset($data['hash']);
$new_data = [];
foreach($data as $key => $value)
$new_data[] = $key . '=' . $value;
sort($new_data);
$data_string = implode('\n', $new_data);
$secret_hash = hash('sha256', $token, true);
$new_hash = hash_hmac('sha256', $data_string, $secret_hash);
if(strcmp($hash, $new_hash) !== 0)
exit('Подмена данных!!!');
echo 'Привет ' . $data['username'];
Попробую разобрать данный код. Сначала мы записываем все полученные данные в переменную $data, далее сохраняем hash в специальную переменную($hash) и удаляем его из массива данных $data. Создаем новый пустой массив($new_data) для наших данных. Используя foreach, мы проходим через все полученные данные, записывая их в наш новый массив($new_data), сохраняя ключ=значение. Сортируем по алфавиту, превращаем в строку $data_string, записывая элементы через \n. Хешируем наш токен($secret_hash), а дальше и все наши данные($new_hash). И последним шагом является проверка подлинности хэша.
Ну и осталось лишь осмотреть все параметры объекта LoginUrl:
- url - указывает url, куда будет отправлен пользователь после нажатия на ссылку.
- forward_text - текст кнопки в пересылаемых сообщениях.
- bot_username - имя бота, через которого будет происходить авторизация.
- request_write_access - запрос на возможность ботом писать пользователю сообщения.
На этом я заканчиваю, надеюсь эта запись будет полезна :)
Татьяна
Ничего, к сожалению, не поняла