1. Go to this page and download the library: Download sitmpcz/oidc 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/ */
sitmpcz / oidc example snippets
declare(strict_types=1);
namespace App\Presenters;
use Nette\Application\UI\Presenter;
use Sitmpcz\oidc\Security\OpenIDClientService;
final class SignPresenter extends Presenter
{
public function __construct(
private OpenIDClientService $oidc
) {}
public function actionLogin(): void
{
$this->redirectUrl($this->oidc->getAuthorizationUrl());
}
public function actionCallback(): void
{
$userinfo = $this->oidc->handleCallback();
// Použijte eventuelně vlastní Authenticator pro přiřazení rolí a oprávnění
$this->getUser()->login($userinfo['preferred_username']);
$this->redirect('Homepage:');
}
public function actionLogout(): void
{
// Získat ID token před odhlášením (nutný pro id_token_hint v OIDC logout URL)
$idToken = $this->oidc->getIdToken();
// Vyčistit lokální session
$this->oidc->logout();
$this->getUser()->logout();
// Přesměrovat na OIDC provider pro globální odhlášení
$this->redirectUrl($this->oidc->getLogoutUrl($idToken));
}
/**
* Endpoint pro backchannel logout - volá ho Keycloak při odhlášení z jiné aplikace
* URL: /sign/out-slo
*/
public function actionOutSlo(): void
{
$logoutToken = $this->getHttpRequest()->getPost('logout_token');
if (!$logoutToken) {
$this->error('Missing logout_token', 400);
}
try {
$success = $this->oidc->handleBackchannelLogout($logoutToken);
if ($success) {
$this->getUser()->logout(true);
}
// OIDC specifikace vyžaduje HTTP 200 bez obsahu
$this->sendResponse(new \Nette\Application\Responses\TextResponse(''));
} catch (\RuntimeException $e) {
$this->error($e->getMessage(), 400);
}
}
}
declare(strict_types=1);
namespace App\Presenters;
use Nette\Application\UI\Presenter;
use Sitmpcz\oidc\Security\OpenIDClientService;
use Predis\ClientInterface as RedisClient;
final class SignPresenter extends Presenter
{
public function __construct(
private OpenIDClientService $oidc,
private RedisClient $redisSession // Redis klient pro sessions (databáze 1)
) {}
public function actionLogin(): void
{
$this->redirectUrl($this->oidc->getAuthorizationUrl());
}
public function actionCallback(): void
{
$userinfo = $this->oidc->handleCallback();
$this->getUser()->login($userinfo['preferred_username']);
$this->redirect('Homepage:');
}
public function actionOut(): void
{
$idToken = $this->oidc->getIdToken();
// Odhlásit lokálně
$this->getUser()->logout();
$this->oidc->logout();
// Zničit celou session včetně dat v Redis
$this->session->destroy();
// Přesměrovat na OIDC logout endpoint (Single Sign-Out)
$this->redirectUrl($this->oidc->getLogoutUrl($idToken));
}
/**
* Backchannel logout endpoint - vyhledává sessions v Redis podle sid/sub
* URL: /sign/out-slo
*/
#[Requires(methods: 'POST')]
public function actionOutSlo(): void
{
$logoutToken = $this->getHttpRequest()->getPost('logout_token');
if (!$logoutToken) {
$this->getHttpResponse()->setCode(\Nette\Http\Response::S400_BadRequest);
$this->sendJson(['error' => 'logout_token parameter is $idB64 = strtr($idParts[1], '-_', '+/');
$idB64 = str_pad($idB64, strlen($idB64) + (4 - strlen($idB64) % 4) % 4, '=');
$idPayload = json_decode(base64_decode($idB64), true);
if (!is_array($idPayload)) {
continue;
}
if (($sid && ($idPayload['sid'] ?? null) === $sid) || ($sub && ($idPayload['sub'] ?? null) === $sub)) {
$this->redisSession->del($sessionKey);
}
}
} while ($cursor !== '0');
$this->sendResponse(new TextResponse(''));
}
}