Авторизация через Telegram — удобный и безопасный способ входа в систему без необходимости запоминать пароли. Telegram предоставляет встроенный механизм авторизации с использованием бота, который передаёт проверенные данные пользователя.
В этой статье рассмотрим, как реализовать авторизацию через Telegram в PHP и Laravel.
Как работает авторизация через Telegram
Telegram предлагает метод авторизации через Telegram Login Widget. Этот механизм позволяет пользователю войти через свой Telegram-аккаунт и передать данные в ваше приложение.
Процесс авторизации выглядит так:
- Пользователь нажимает на кнопку входа через Telegram.
- Telegram отображает окно подтверждения.
- После успешного входа Telegram перенаправляет пользователя обратно на сайт с его данными.
- Сервер проверяет подлинность данных и выполняет авторизацию.
Настройка бота в Telegram
Перед началом работы необходимо создать бота в Telegram:
- Открываем @BotFather и отправляем команду
/newbot
. - Придумываем имя и username для бота.
- Получаем токен API бота, который понадобится для верификации данных.
- Переходим в настройки бота, в раздел «Bot Settings->Domain» и указываем домен сайта, на котором будем настраивать авторизацию.
Авторизация на чистом PHP
Для настройки авторизации на чистом PHP вам необходимо разместить кнопку, на вашем сайте.
<script async src="https://telegram.org/js/telegram-widget.js?15"
data-telegram-login="{TELEGRAM_BOT_USERNAME}"
data-size="large"
data-auth-url="{путь до файла обработчика}"
data-request-access="write"></script>
После успешной авторизации, ответ от Telegram бота будет отправлен на указанный скрипт. В ответе вы получите массив с данными о пользователе.
Пример данных:
[
"id" => "1424126511"
"first_name" => "Илья"
"last_name" => "Лящук"
"username" => "iliyalyachuk"
"photo_url" => "https://t.me/i/userpic/320/1ICerdfdsfvCa5QqgLqT5RI.jpg"
"auth_date" => "1742509532"
"hash" => "9306b4eec36f0asda73ffde3d5fea29a58b1585656a124af"
]
Далее вы записываете данные в БД и фиксируете, что пользователь авторизован.
Настройка авторизации на PHP и Laravel
Для более ООП-ориентированной реализации с учётом лучших практик Laravel, мы можем выделить несколько компонентов, чтобы код был чистым, тестируемым и следовал принципам SOLID.
Для начала нам необходимо занести информации о боте в переменные, в env файл:
TELEGRAM_BOT_TOKEN='7556733496:AAEjTNztVTdbasdjSf8-gt_bMO3QndQrCDFI'
TELEGRAM_BOT_USERNAME='prog_time_auth_bot'
После, создадим сервисный класс, который будет отвечать за логику авторизации.
Создайте класс в папке app/Services
/TelegramAuthService.php
. Этот сервис будет заниматься валидацией данных от Telegram и регистрацией/авторизацией пользователей.
namespace App\Services;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
class TelegramAuthService
{
/**
* Валидирует данные, полученные от Telegram
*
* @param array $data
* @return bool
*/
public function validateTelegramData(array $data): bool
{
$check_hash = $data['hash'];
unset($data['hash']);
ksort($data); // Сортируем массив
$data_check_string = '';
foreach ($data as $key => $value) {
$data_check_string .= "$key=$value\n";
}
$bot_token = env('TELEGRAM_BOT_TOKEN');
$secret_key = hash('sha256', $bot_token, true);
$hash = hash_hmac('sha256', trim($data_check_string), $secret_key);
return hash_equals($hash, $check_hash);
}
/**
* Авторизует пользователя или создает нового
*
* @param array $data
* @return \App\Models\User
*/
public function authenticateOrCreateUser(array $data): User
{
// Ищем пользователя по Telegram ID, если нет — создаем
return User::firstOrCreate([
'telegram_id' => $data['id'],
], [
'name' => $data['first_name'] ?? 'Unknown',
'email' => $data['email'] ?? 'telegram@user.ru',
'username' => $data['username'] ?? null,
'avatar' => $data['photo_url'] ?? null,
'password' => Hash::make(Str::random(16)),
]);
}
}
Важный момент! Если вы используете стандартную схему таблицы users от Laravel, то система будет выдать ошибку связанную с обязательным заполнением поле «email» и «пароль» . Вы можете сгенерировать данные для этих полей в процессе добавления пользователя или изменить обязательность полей в БД.
Далее, создадим контроллер, который будет обрабатывать запросы и взаимодействовать с сервисом.
Выполните команду для создания контроллера:
php artisan make:controller TelegramAuthController
В файле app/Http/Controllers/TelegramAuthController.php
будет следующий код:
namespace App\Http\Controllers;
use App\Services\TelegramAuthService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class TelegramAuthController extends Controller
{
protected $telegramAuthService;
public function __construct(TelegramAuthService $telegramAuthService)
{
$this->telegramAuthService = $telegramAuthService;
}
/**
* Обрабатывает callback от Telegram и выполняет авторизацию
*
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function callback(Request $request)
{
$data = $request->all();
// Валидируем данные от Telegram
if (!$this->telegramAuthService->validateTelegramData($data)) {
abort(403, 'Данные недействительны');
}
// Авторизуем пользователя или создаем нового
$user = $this->telegramAuthService->authenticateOrCreateUser($data);
// Авторизация пользователя в системе
Auth::login($user);
return redirect()->route('dashboard'); // Перенаправление на главную страницу
}
}
Теперь необходимо добавить маршрут в routes/web.php
use App\Http\Controllers\AuthController;
use App\Http\Controllers\TelegramAuthController;
use Illuminate\Support\Facades\Route;
/* принимает ответ от Telegram */
Route::get('/auth/telegram/callback', [TelegramAuthController::class, 'callback'])->name('auth.telegram.callback');
/* страница авторизации */
Route::get('/login', [AuthController::class, 'showLoginPage'])->name('login');
/* страница админки, доступная только для авторизованных */
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware('auth')->name('dashboard');
Далее необходимо создать миграцию для добавления дополнительных полей в таблицу с пользователями.
php artisan make:migration add_telegram_fields_to_users_table
Миграция в файле database/migrations/xxxx_xx_xx_xxxxxx_add_telegram_fields_to_users_table.php
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->bigInteger('telegram_id')->unique()->nullable();
$table->string('username')->nullable();
$table->string('avatar')->nullable();
});
}
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn(['telegram_id', 'username', 'avatar']);
});
}
Применяем миграцию:
php artisan migrate
Теперь сделаем страницу авторизации.
Для начала создадим контроллер:
namespace App\Http\Controllers;
use Illuminate\Contracts\View\View;
class AuthController extends Controller
{
/**
* Показывает страницу входа
* @return View
*/
public function showLoginPage(): View
{
return view('auth.telegram-login');
}
}
Далее создаём представление resources/views/auth/telegram-login.blade.php
, для страницы авторизации
...
<div class="container">
<h2>Вход через Telegram</h2>
<p>Нажмите кнопку ниже, чтобы войти:</p>
<script async src="https://telegram.org/js/telegram-widget.js?15"
data-telegram-login="{{ env('TELEGRAM_BOT_USERNAME') }}"
data-size="large"
data-auth-url="{{ route('auth.telegram.callback') }}"
data-request-access="write"></script>
</div>
...
Разбор параметров:
data-telegram-login
— имя вашего бота.data-size
— размер кнопки (small
,medium
,large
).data-auth-url
— URL, куда будут отправлены данные после успешной авторизации.data-request-access
— запрашиваемые разрешения (по умолчаниюwrite
).
После нажатия на кнопку пользователю будет предложено войти в Telegram и подтвердить вход.
Последним этапом, создаём представление для страницы, которая будет открываться после авторизации. Но это уже на ваше усмотрение!
Итог
Теперь у вас есть готовая авторизация через Telegram в Laravel. Пользователь нажимает кнопку входа, Telegram передаёт данные, Laravel проверяет их и создаёт пользователя.
Эта система удобна и безопасна, так как Telegram уже выполняет проверку личности пользователя.
Попробуйте внедрить этот метод в своё приложение и упростите процесс авторизации для пользователей!