PHP code example of tigusigalpa / sber-id-php
1. Go to this page and download the library: Download tigusigalpa/sber-id-php library . Choose the download type require .
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
tigusigalpa / sber-id-php example snippets
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('sberid_sub')->nullable()->unique()->after('id');
$table->text('sberid_access_token')->nullable();
$table->text('sberid_refresh_token')->nullable();
$table->timestamp('sberid_token_expires_at')->nullable();
$table->timestamp('last_login_at')->nullable();
});
}
use Tigusigalpa\SberID\Facades\SberID;
public function redirectToSberID()
{
$state = \Illuminate\Support\Str::random(40);
$nonce = \Illuminate\Support\Str::random(40);
session(['sberid_state' => $state, 'sberid_nonce' => $nonce]);
$authUrl = SberID::getAuthorizationUrl($state, $nonce);
return redirect($authUrl);
}
use Tigusigalpa\SberID\Facades\SberID;
use Tigusigalpa\SberID\Exceptions\SberIDException;
public function handleCallback(Request $request)
{
$code = $request->input('code');
$state = $request->input('state');
// Проверка state
if ($state !== session('sberid_state')) {
abort(403, 'Неверный параметр state');
}
try {
// Обмен кода на токены
$tokenData = SberID::getAccessToken($code);
$accessToken = $tokenData['access_token'];
$refreshToken = $tokenData['refresh_token'] ?? null;
// Получение информации о пользователе
$userInfo = SberID::getUserInfo($accessToken);
// Отправка аналитики (только production)
SberID::confirmAuthenticationSuccess($accessToken);
// Создание или обновление пользователя в БД
$user = User::updateOrCreate(
['sberid_sub' => $userInfo['sub']],
[
'email' => $userInfo['email'] ?? null,
'phone' => $userInfo['phone_number'] ?? null,
'name' => $userInfo['given_name'] ?? null,
'family_name' => $userInfo['family_name'] ?? null,
]
);
// Авторизация пользователя
auth()->login($user);
return redirect()->route('home');
} catch (SberIDException $e) {
return redirect()->route('login')
->with('error', 'Ошибка авторизации: ' . $e->getMessage());
}
}
use Tigusigalpa\SberID\Facades\SberID;
public function refreshToken($refreshToken)
{
try {
$tokenData = SberID::refreshAccessToken($refreshToken);
$newAccessToken = $tokenData['access_token'];
$newRefreshToken = $tokenData['refresh_token'] ?? null;
// Обновление сохраненных токенов
return $newAccessToken;
} catch (SberIDException $e) {
// Обработка ошибки
}
}
Tigusigalpa\SberID\SberIDClient;
use Tigusigalpa\SberID\Exceptions\SberIDException;
// Запуск сессии для управления state
session_start();
// Инициализация клиента
$client = new SberIDClient([
'environment' => 'sandbox', // или 'production'
'client_id' => 'ваш-client-id',
'client_secret' => 'ваш-client-secret',
'redirect_uri' => 'https://ваш-домен.ru/callback.php',
'scopes' => 'openid name email phone',
'request_refresh_token' => true,
'certificate_path' => null, // Путь к сертификату для production
'certificate_password' => null,
'verify_ssl' => true,
'send_analytics' => true,
'timeout' => 10,
]);
re_once 'client.php'; // Файл с инициализацией клиента
// Генерация state и nonce для безопасности
$state = bin2hex(random_bytes(20));
$nonce = bin2hex(random_bytes(20));
// Сохранение в сессии
$_SESSION['sberid_state'] = $state;
$_SESSION['sberid_nonce'] = $nonce;
// Получение URL авторизации
$authUrl = $client->getAuthorizationUrl($state, $nonce);
// Перенаправление пользователя
header('Location: ' . $authUrl);
exit;
re_once 'client.php'; // Файл с инициализацией клиента
// Получение параметров из callback
$code = $_GET['code'] ?? null;
$state = $_GET['state'] ?? null;
$error = $_GET['error'] ?? null;
// Обработка ошибки
if ($error) {
$errorDescription = $_GET['error_description'] ?? 'Неизвестная ошибка';
die("Ошибка авторизации: {$error} - {$errorDescription}");
}
// Проверка параметра state
if (!$state || $state !== $_SESSION['sberid_state']) {
die('Неверный параметр state. Возможна CSRF атака.');
}
// Очистка state из сессии
unset($_SESSION['sberid_state'], $_SESSION['sberid_nonce']);
if (!$code) {
die('Код авторизации не получен');
}
try {
// Обмен кода на токены
$tokenData = $client->getAccessToken($code);
$accessToken = $tokenData['access_token'];
$refreshToken = $tokenData['refresh_token'] ?? null;
$idToken = $tokenData['id_token'] ?? null;
// Получение информации о пользователе
$userInfo = $client->getUserInfo($accessToken);
// Декодирование ID токена (опционально)
if ($idToken) {
$idTokenData = $client->decodeIdToken($idToken);
}
// Отправка аналитики (только production)
$client->confirmAuthenticationSuccess($accessToken);
// Сохранение данных пользователя в сессии или БД
$_SESSION['user'] = [
'id' => $userInfo['sub'],
'email' => $userInfo['email'] ?? null,
'phone' => $userInfo['phone_number'] ?? null,
'name' => $userInfo['given_name'] ?? null,
'family_name' => $userInfo['family_name'] ?? null,
'middle_name' => $userInfo['middle_name'] ?? null,
];
// Сохранение токенов безопасно (шифруйте в production!)
$_SESSION['access_token'] = $accessToken;
$_SESSION['refresh_token'] = $refreshToken;
$_SESSION['token_expires_at'] = time() + $tokenData['expires_in'];
// Перенаправление на защищенную страницу
header('Location: /dashboard.php');
exit;
} catch (SberIDException $e) {
die('Ошибка авторизации: ' . $e->getMessage() .
' (Код: ' . $e->getErrorCode() . ')');
}
re_once 'client.php';
$refreshToken = $_SESSION['refresh_token'] ?? null;
if (!$refreshToken) {
die('Refresh token недоступен');
}
try {
$tokenData = $client->refreshAccessToken($refreshToken);
// Обновление токенов в сессии
$_SESSION['access_token'] = $tokenData['access_token'];
$_SESSION['refresh_token'] = $tokenData['refresh_token'] ?? $refreshToken;
$_SESSION['token_expires_at'] = time() + $tokenData['expires_in'];
echo "Токен успешно обновлен!";
} catch (SberIDException $e) {
// Refresh token истек или недействителен - нужна повторная авторизация
unset($_SESSION['access_token'], $_SESSION['refresh_token']);
header('Location: /login.php');
exit;
}
session_start();
// Проверка авторизации пользователя
if (!isset($_SESSION['user'])) {
header('Location: /login.php');
exit;
}
// Проверка необходимости обновления токена
if (isset($_SESSION['token_expires_at']) && time() >= $_SESSION['token_expires_at']) {
// Токен истек, попытка обновления
header('Location: /refresh.php');
exit;
}
$user = $_SESSION['user'];
// callback.php с сохранением в БД через PDO
ew PDO('mysql:host=localhost;dbname=myapp', 'username', 'password');
// ... код проверки state ...
try {
$tokenData = $client->getAccessToken($code);
$userInfo = $client->getUserInfo($tokenData['access_token']);
// Проверка существования пользователя
$stmt = $pdo->prepare('SELECT * FROM users WHERE sberid_sub = ?');
$stmt->execute([$userInfo['sub']]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user) {
// Обновление существующего пользователя
$stmt = $pdo->prepare('
UPDATE users
SET email = ?,
phone = ?,
sberid_access_token = ?,
sberid_refresh_token = ?,
sberid_token_expires_at = ?,
last_login_at = NOW()
WHERE sberid_sub = ?
');
$stmt->execute([
$userInfo['email'] ?? null,
$userInfo['phone_number'] ?? null,
$tokenData['access_token'],
$tokenData['refresh_token'] ?? null,
date('Y-m-d H:i:s', time() + $tokenData['expires_in']),
$userInfo['sub']
]);
} else {
// Создание нового пользователя
$stmt = $pdo->prepare('
INSERT INTO users (
sberid_sub, email, phone, name, family_name, middle_name,
sberid_access_token, sberid_refresh_token,
sberid_token_expires_at, created_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
');
$stmt->execute([
$userInfo['sub'],
$userInfo['email'] ?? null,
$userInfo['phone_number'] ?? null,
$userInfo['given_name'] ?? null,
$userInfo['family_name'] ?? null,
$userInfo['middle_name'] ?? null,
$tokenData['access_token'],
$tokenData['refresh_token'] ?? null,
date('Y-m-d H:i:s', time() + $tokenData['expires_in'])
]);
}
// Установка сессии
$_SESSION['user_id'] = $userInfo['sub'];
header('Location: /dashboard.php');
exit;
} catch (SberIDException $e) {
die('Ошибка: ' . $e->getMessage());
}
namespace App\Http\Controllers;
use Tigusigalpa\SberID\Http\Controllers\SberIDController as BaseSberIDController;
class CustomSberIDController extends BaseSberIDController
{
protected function handleSuccess(array $userInfo, string $accessToken, ?string $refreshToken)
{
// Ваша логика успешной авторизации
$user = User::firstOrCreate(
['sberid_sub' => $userInfo['sub']],
['email' => $userInfo['email'] ?? null]
);
auth()->login($user);
return redirect()->route('dashboard');
}
protected function handleError(string $error, string $description)
{
// Ваша обработка ошибок
\Log::error("Ошибка Sber ID: {$error} - {$description}");
return redirect()->route('login')
->with('error', 'Не удалось войти через Сбер ID');
}
}
[
'access_token' => 'string', // Access token (60 секунд)
'token_type' => 'bearer',
'expires_in' => 60,
'scope' => 'openid name email',
'id_token' => 'string',
'refresh_token' => 'string' // Refresh token (30 дней)
]
'scopes' => 'openid email'
'scopes' => 'openid name email phone'
'scopes' => 'openid name birthdate identification inn snils address_reg'
'scopes' => 'openid name phone delivery_address'
use Illuminate\Support\Facades\Log;
try {
$tokenData = SberID::getAccessToken($code);
Log::info('Токен получен', ['expires_in' => $tokenData['expires_in']]);
} catch (SberIDException $e) {
Log::error('Ошибка Sber ID', [
'error_code' => $e->getErrorCode(),
'error_description' => $e->getErrorDescription(),
]);
}
use Tigusigalpa\SberID\SberIDClient;
use Mockery;
$mockClient = Mockery::mock(SberIDClient::class);
$mockClient->shouldReceive('getAccessToken')
->andReturn([
'access_token' => 'test-token',
'token_type' => 'bearer',
'expires_in' => 60,
]);
$this->app->instance(SberIDClient::class, $mockClient);
'sberid_access_token' => encrypt($accessToken),
'sberid_refresh_token' => encrypt($refreshToken),
// Плохо
Log::info('Token: ' . $accessToken);
// Хорошо
Log::info('Токен получен', ['token_length' => strlen($accessToken)]);
if ($state !== session('sberid_state')) {
abort(403, 'Неверный параметр state');
}
$state = \Illuminate\Support\Str::random(40);
// config/session.php
'secure' => env('SESSION_SECURE_COOKIE', true),
'http_only' => true,
'same_site' => 'lax',
$code = $request->input('code');
if (!$code || !is_string($code)) {
abort(400, 'Неверный код авторизации');
}
Route::middleware(['throttle:10,1'])->group(function () {
Route::get('/auth/sberid/redirect', [SberIDController::class, 'redirect']);
Route::get('/auth/sberid/callback', [SberIDController::class, 'callback']);
});
// Плохо
return response()->json(['error' => $e->getMessage()]);
// Хорошо
Log::error('Ошибка авторизации', ['exception' => $e]);
return response()->json(['error' => 'Ошибка авторизации']);
// Хорошо - Laravel ORM
User::where('sberid_sub', $sub)->first();
// Избегайте сырых запросов с пользовательским вводом
bash
composer bash
php artisan vendor:publish --tag=sberid-config
bash
php artisan migrate