Авторизация через Steam на PHP в 2025: Выкидываем LightOpenID и пишем нативный код (PHP 8.1)
Привет, Хабр!
Любой, кто делал магазины скинов, рулетки или просто игровые форумы, сталкивался с задачей: "Сделать кнопку Войти через Steam".
Казалось бы, задача тривиальная. Идем в гугл, пишем php steam auth, и что мы видим?
Библиотеку LightOpenID, которая не обновлялась лет 10.
Советы использовать огромные фреймворки ради одной кнопки.
Код на StackOverflow, где данные пользователя вытаскиваются регулярками из XML (что уже само по себе больно).
В 2025 году использовать код, написанный под PHP 5.6, стыдно. Массивы типа $user['personaname'] без подсказок IDE, отсутствие типизации, непонятные ошибки cURL...
Я решил, что хватит это терпеть, и написал SteamAuthZero.
🛠 В чем проблема существующих решений?
Steam использует протокол OpenID 2.0. Он старый, но рабочий. Большинство библиотек тянут за собой Guzzle или Curl-обертки, весящие мегабайты. Другие — просто "портянки" спагетти-кода, которые страшно класть в папку vendor.
Мне нужно было решение, которое:
Не имеет зависимостей (Zero Dependencies).
Работает на PHP 8.1+ (строгая типизация).
Возвращает нормальный DTO объект, а не безликий массив.
Легко подключается через обычный
require.
🚀 Как это работает теперь
Вместо того чтобы гадать, что вернет Steam, мы используем строгие объекты.
Было (старый подход):
// Какой-то код из 2015 года
if($openid->validate()) {
$data = $openid->getAttributes();
echo $data['namePerson/friendly']; // Или personaname? Или name? Приходилось гуглить.
}
Стало (SteamAuthZero):
$auth = new SteamAuthZero($returnUrl, $apiKey);
$steamId = $auth->validate();
if ($steamId) {
$user = $auth->getUserInfo($steamId);
// IDE сама подсказывает поля!
echo $user->personaName;
echo $user->avatarUrl;
}
Что под капотом?
Библиотека предельно простая.
Валидация: Проверяет подпись, которую вернул Steam (параметры
openid_sig,openid_signed), отправляя легкий запрос обратно на сервер Valve.Получение данных: Делает запрос к
ISteamUser/GetPlayerSummaries, используя нативные PHP потоки (stream_context) или cURL (если потоки закрыты).DTO: Мапит JSON ответ от Steam в удобный класс
SteamUser.
Результат
Получилась библиотека весом в пару килобайт, которую можно просто закинуть в проект и забыть о проблемах с совместимостью. Никакого "composer hell", никаких конфликтов версий.
Если вы пишете пет-проекты, игровые магазины или админки для серверов — буду рад, если решение пригодится.
Ссылка на репозиторий
(Буду благодарен за звезды!)