WebWost WebWostbeta

Авторизация через Telegram бота

Авторизация через Telegram бота. Передача параметров пользователя из Telegram.

PHP

Al-Sher

Всем привет. Давно ничего не писал, так как не было никаких идей, но недавно, 31 мая 2019 года, Telegram выпустил новое обновление, в котором добавил новый тип данных - LoginUrl. Итак, попробую объяснить идею авторизации с помощью Telegram бота. Для начала, чтобы бот мог писать пользователю, пользователь должен отправить сообщение /start. Бот может как угодно ответить на это сообщение, например обычным приветствием или набором кнопок для взаимодействия с ботом. Именно кнопками мы и будем пользоваться для авторизации, но об этом чуть позже. Пользователь жмет на нашу кнопку, после чего перед ним появляется окошко с подтверждением действия. Если пользователь подтверждает свое действие, то он переходит на указанный в параметрах url с данными своего аккаунта, в том числе и уникальный id для пользователя.

Начнем. Для начала необходимо написать боту @BotFather для создания нашего бота. Ответив на несколько вопросов мы получим токен, с помощью которого можно управлять ботом. Далее нам необходимо добавить сайт для бота. Для этого пишем @BotFather сообщение /setdomain. Там нас спрашивают какому боту мы хотим указать url, выбираем нужного и указываем необходимый домен. Следующим шагом необходимо настроить получение сообщений ботом от пользователя. Этот шаг я описывать не буду, лишь скажу что Telegram поддерживает как ручную проверку обновлений (метод getUpdates), так и установку Webhook(метод setWebhook). Ну и конечно же нам необходимо отправлять сообщение пользователю с помощью метода sendMessage. Вот на нем я и остановлюсь подробнее. Данный метод принимает следующие параметры:

Как можно было догадаться, нам необходимы 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:

На этом я заканчиваю, надеюсь эта запись будет полезна :)

1 комментариий

Загрузить еще комментариев

Новый комментарий