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