misha-in / sso-client
Jednoduchý PHP klient pro integraci s SSO serverem pomocí OAuth 2.0 (Authorization Code + PKCE).
Requires
- php: >=8.1
- ext-curl: *
This package is not auto-updated.
Last update: 2026-04-23 22:31:27 UTC
README
Jednoduchý PHP klient pro integraci s SSO serverem id.produkce.ai pomocí OAuth 2.0 (Authorization Code + PKCE).
Nevyžaduje žádné závislosti – používá pouze PHP curl a cookies.
Požadavky
- PHP 8.1+
- Rozšíření
curl
Instalace
Composer (doporučeno)
composer require misha-in/sso-client
use MishaIn\SsoClient\SsoClient;
Bez Composeru
require_once __DIR__ . '/SsoClient.php';
Konfigurace
$sso = new SsoClient([
'client_id' => 'my-app', // ID klienta registrovaného na SSO
'client_secret' => 'tajny-klic', // Tajný klíč klienta
'redirect_uri' => 'https://app.example.com/callback', // Callback URL registrovaná na SSO
]);
Poznámka k scopům: Klient neposílá seznam požadovaných scopů. SSO server automaticky vrátí všechna oprávnění, která má přihlášený uživatel přiřazena pro danou aplikaci. Správa oprávnění probíhá výhradně na SSO serveru v administraci.
Použití
1. Přihlášení – přesměrování na SSO
$sso->redirectToLogin();
// Funkce ukončí skript přesměrováním (exit).
Interně se vygeneruje state (ochrana proti CSRF) a code_verifier (PKCE), které se uloží do
krátkodobých cookies (platnost 10 minut, SameSite=Lax).
2. Callback – výměna kódu za tokeny
Na callback URL (registrované na SSO) zpracujte parametry z $_GET:
$code = $_GET['code'] ?? '';
$state = $_GET['state'] ?? '';
try {
$tokens = $sso->handleCallback($code, $state);
// $tokens['access_token'] – přístupový token (platnost 1 hodina)
// $tokens['refresh_token'] – obnovovací token (platnost 1 měsíc)
// $tokens['expires_in'] – platnost access tokenu v sekundách (3600)
// $tokens['token_type'] – "Bearer"
} catch (RuntimeException $e) {
// Neplatný state (CSRF) nebo chyba serveru
die('Přihlášení selhalo: ' . $e->getMessage());
}
Tokeny jsou automaticky uloženy do $_SESSION – klient je spravuje automaticky.
3. Informace o uživateli
$user = $sso->getUserInfo($tokens['access_token']);
// $user['sub'] – ID uživatele (int)
// $user['email'] – e-mailová adresa
// $user['name'] – celé jméno
// $user['scopes'] – pole přidělených oprávnění, např. ['dashboard', 'articles.faq', 'role.admin']
Scopy jsou ve formátu dot-notace: parent.child. Scope bez rodiče je jen identifier (např. dashboard).
4. Kontrola oprávnění (scope)
if ($sso->hasScope('articles.faq')) {
// uživatel má přístup k articles.faq
}
Metoda interně zavolá getUserInfo() – doporučuje se výsledek cachovat na úrovni aplikace
(např. ukládat $user do session po dobu přihlášení).
5. Ověření přihlášení
if (!$sso->isAuthenticated()) {
$sso->redirectToLogin();
}
Metoda automaticky obnoví access token pomocí refresh tokenu, pokud vypršel. Pokud obnova selže
(refresh token expiroval), vrátí false.
6. Platný access token
Pro přímou práci s tokenem (např. vlastní API volání):
$accessToken = $sso->getValidAccessToken();
if ($accessToken === null) {
$sso->redirectToLogin(); // session vypršela
}
7. Obnovení tokenu
Access token se obnovuje automaticky při volání isAuthenticated() a getValidAccessToken().
Pokud potřebujete obnovit token ručně:
try {
$newTokens = $sso->refreshToken($refreshToken);
} catch (RuntimeException $e) {
// Refresh token vypršel – přesměrujte na přihlášení
$sso->redirectToLogin();
}
8. Odhlášení
$sso->logout();
// nebo s přesměrováním po odhlášení:
$sso->logout('https://app.example.com/');
Pro sestavení URL bez okamžitého přesměrování (např. odkaz v šabloně):
$logoutUrl = $sso->getLogoutUrl('https://app.example.com/');
Kompletní příklad integrace
<?php
session_start();
require_once __DIR__ . '/SsoClient.php';
use MishaIn\SsoClient\SsoClient;
$sso = new SsoClient([
'client_id' => 'my-app',
'client_secret' => 'tajny-klic',
'redirect_uri' => 'https://app.example.com/callback',
]);
$action = $_GET['action'] ?? '';
// Přihlášení
if ($action === 'login') {
$sso->redirectToLogin();
}
// Callback ze SSO
if ($action === 'callback') {
try {
$sso->handleCallback($_GET['code'] ?? '', $_GET['state'] ?? '');
header('Location: /dashboard');
exit;
} catch (RuntimeException $e) {
die('Chyba přihlášení: ' . $e->getMessage());
}
}
// Odhlášení
if ($action === 'logout') {
$sso->logout('https://app.example.com/');
}
// Chráněná stránka
if (!$sso->isAuthenticated()) {
$sso->redirectToLogin();
}
$accessToken = $sso->getValidAccessToken();
$user = $sso->getUserInfo($accessToken);
echo 'Přihlášen jako: ' . htmlspecialchars($user['name']);
echo 'Oprávnění: ' . implode(', ', $user['scopes']);
// Kontrola konkrétního oprávnění
if ($sso->hasScope('articles.faq')) {
echo 'Má přístup k FAQ.';
}
Přehled metod
| Metoda | Návratový typ | Popis |
|---|---|---|
redirectToLogin(): never | – | Přesměruje uživatele na SSO přihlašovací stránku |
handleCallback(string $code, string $state): array | tokeny | Vymění authorization code za tokeny, uloží do session |
isAuthenticated(): bool | bool | Vrátí true pokud je uživatel přihlášen (automaticky obnoví token) |
getValidAccessToken(): ?string | string|null | Vrátí platný access token nebo null pokud session vypršela |
getUserInfo(string $accessToken): array | user array | Vrátí data uživatele vč. pole scopes |
hasScope(string $scope): bool | bool | Zkontroluje, zda má uživatel dané oprávnění |
refreshToken(string $refreshToken): array | tokeny | Ručně obnoví access token |
isTokenValid(string $accessToken): bool | bool | Ověří platnost tokenu dotazem na SSO |
getLogoutUrl(?string $redirectUri = null): string | string | Vrátí URL pro odhlášení (bez přesměrování) |
logout(?string $redirectUri = null): never | – | Odhlásí uživatele a přesměruje na SSO |
Formát scopů
Oprávnění jsou ve formátu dot-notace odpovídající hierarchii definované na SSO serveru:
rag – přístup k celému rag modulu
rag.faq – přístup k faq v rámci rag
rag.files – přístup k files v rámci rag
rag.prompt – přístup k prompt v rámci rag
role.root – role root
Každý uživatel má oprávnění spravována administrátorem přímo na SSO serveru. Aplikace scopy nežádá – dostane automaticky vše, co má daný uživatel přiřazeno.
Bezpečnostní poznámky
- CSRF ochrana:
stateparametr je generován pomocírandom_bytes(32)a ověřován přeshash_equals(). - PKCE: Každý login flow používá unikátní
code_verifier(S256) – chrání i při úniku authorization code. - Tajný klíč (
client_secret) nikdy neopouští server – nikdy ho nevkládejte do front-endového kódu nebo do verzovacího systému. - Tokeny jsou ukládány do
$_SESSIONna straně serveru.