Installation
composer require ekapusta/oauth2-esia-bundle
Register the bundle in config/app.php under providers:
Ekapusta\OAuth2EsiaBundle\EkapustaOAuth2EsiaBundle::class,
Basic Configuration
Add ESIA OAuth2 settings to config/packages/ekapusta_oauth2_esia.yaml:
client_id: "YOUR_SYSTEM_ID"
redirect_uri: "https://your-app.com/auth/esia/callback"
signer:
class_name: Ekapusta\OAuth2Esia\Security\Signer\OpensslCli
certificate_path: "%kernel.project_dir%/config/esia/public.cer"
private_key_path: "%kernel.project_dir%/config/esia/private.key"
private_key_password: "your_private_key_password"
tool_path: "/usr/bin/openssl"
First Use Case: Authentication Flow
Use the OAuth2EsiaAuthenticator service to initiate login:
use Ekapusta\OAuth2EsiaBundle\Security\Auth\OAuth2EsiaAuthenticator;
$authenticator = app(OAuth2EsiaAuthenticator::class);
$authUrl = $authenticator->getLoginUrl();
// Redirect user to $authUrl
Initiate Login Redirect users to ESIA with pre-signed request:
$authenticator = app(OAuth2EsiaAuthenticator::class);
return redirect()->to($authenticator->getLoginUrl());
Handle Callback
Use the CallbackController (included in the bundle) or implement your own:
public function callback(OAuth2EsiaAuthenticator $authenticator)
{
$user = $authenticator->authenticateRequest($request);
// Handle authenticated user (e.g., create/update session)
}
Token Management Fetch and validate tokens post-authentication:
$token = $authenticator->getAccessToken();
$userInfo = $authenticator->getUserInfo($token);
Symfony Security Component
Extend AbstractGuardAuthenticator for seamless integration with Symfony’s security system:
use Ekapusta\OAuth2EsiaBundle\Security\Auth\OAuth2EsiaAuthenticator as BaseAuthenticator;
class CustomEsiaAuthenticator extends BaseAuthenticator
{
public function supports(Request $request)
{
return $request->isMethod('GET') && $request->getPathInfo() === '/login/esia';
}
}
Environment Variables
Store sensitive paths (e.g., private_key_path) in .env:
ESIA_CERT_PATH=%kernel.project_dir%/config/esia/public.cer
ESIA_KEY_PATH=%kernel.project_dir%/config/esia/private.key
Reference them in config:
signer:
certificate_path: "%env(ESIA_CERT_PATH)%"
Testing
Use the EsiaOAuth2Client service directly for unit tests:
$client = $this->container->get('ekapusta_oauth2_esia.client');
$response = $client->fetchAccessToken($code);
Certificate Validation
certificate_path and private_key_path point to valid, paired files. Verify with:
openssl x509 -in public.cer -text -noout
openssl rsa -in private.key -check
Redirect URI Mismatch
redirect_uri in config doesn’t match the registered URI.config/packages/ekapusta_oauth2_esia.yaml and register it in the ESIA developer portal.Openssl CLI Dependency
OpensslCli signer requires openssl binary in PATH.openssl in tool_path or ensure it’s in the system PATH.Token Expiry
Enable Verbose Logging
Add to config/packages/monolog.yaml:
handlers:
esia:
type: stream
path: "%kernel.logs_dir%/esia.log"
level: debug
channels: ["ekapusta_oauth2_esia"]
Then enable the channel in config/packages/ekapusta_oauth2_esia.yaml:
logging: true
Check Raw Responses Inspect the raw OAuth2 response for errors:
$response = $client->fetchAccessToken($code);
if ($response->isError()) {
\Log::error('ESIA Error:', ['response' => $response->getBody()]);
}
Custom User Provider
Override the default user mapping by extending the EsiaUserProvider:
use Ekapusta\OAuth2EsiaBundle\Security\User\EsiaUserProvider as BaseProvider;
class CustomEsiaUserProvider extends BaseProvider
{
protected function mapUserInfoToUser(array $userInfo)
{
return new User([
'id' => $userInfo['snils'] ?? null,
'name' => $userInfo['name'] ?? null,
// Custom logic
]);
}
}
Register it in config/packages/ekapusta_oauth2_esia.yaml:
user_provider: App\Security\User\CustomEsiaUserProvider
State Management For CSRF protection, implement a custom state generator:
use Ekapusta\OAuth2EsiaBundle\Security\Auth\StateGeneratorInterface;
class CustomStateGenerator implements StateGeneratorInterface
{
public function generate(): string
{
return bin2hex(random_bytes(32));
}
}
Bind it in services.yaml:
Ekapusta\OAuth2EsiaBundle\Security\Auth\StateGeneratorInterface: '@App\Security\Auth\CustomStateGenerator'
Multi-Tenant Support
Dynamically set client_id based on tenant:
$authenticator->setClientId(Tenant::current()->esiaClientId);
How can I help you explore Laravel packages today?