obsidiane/auth-sdk
Composer 安装命令:
composer require obsidiane/auth-sdk
包简介
Symfony bundle fournissant un client Obsidiane Auth orienté API (bridge + facades, Bearer token)
README 文档
README
SDK PHP orienté API pour consommer Obsidiane Auth avec une logique proche du SDK JS (bridge + facades). Authentification via Bearer token (optionnel), pas de cookies.
Features
✅ Bridge API-first (get/getCollection/post/patch/put/delete + request)
✅ Facades ressources avec modèles hydratés via Symfony Serializer
✅ JSON-LD par défaut (Accept: application/ld+json)
✅ Content-Type auto (POST/PUT: application/ld+json, PATCH: application/merge-patch+json)
✅ Exceptions structurées via ApiErrorException sur erreurs HTTP
✅ Configuration Symfony simple et explicite
Installation
composer require obsidiane/auth-sdk
Configuration Symfony
config/bundles.php
return [ // ... Obsidiane\AuthBundle\ObsidianeAuthBundle::class => ['all' => true], ];
config/packages/obsidiane_auth.yaml
obsidiane_auth: base_url: '%env(OBSIDIANE_AUTH_BASE_URL)%' token: '%env(OBSIDIANE_AUTH_TOKEN)%' # optionnel defaults: headers: { } timeout_ms: 10000 # optionnel debug: false
.env
OBSIDIANE_AUTH_BASE_URL=https://auth.example.com OBSIDIANE_AUTH_TOKEN=your-static-bearer-token
Le token est optionnel : s'il est absent ou vide, aucun header Authorization n'est ajouté (utile pour les endpoints publics).
base_url est requis et peut inclure ou non /api selon votre usage (adaptez vos routes en conséquence).
Utilisation
FacadeFactory (ressources)
use Obsidiane\AuthBundle\Bridge\FacadeFactory; final class UsersService { public function __construct( private readonly FacadeFactory $factory, ) {} public function listUsers(): array { $users = $this->factory->create('/api/users', \App\Dto\UserRead::class); $result = $users->getCollection(); return $result->items; // list<UserRead> } }
BridgeFacade (endpoints custom)
use Obsidiane\AuthBundle\Bridge\BridgeFacade; final class AuthService { public function __construct( private readonly BridgeFacade $bridge, ) {} public function me(): array { return $this->bridge->get('/api/auth/me'); } }
Requête custom avec HttpRequestConfig
use Obsidiane\AuthBundle\Bridge\Http\HttpRequestConfig; $req = new HttpRequestConfig( method: 'GET', url: '/api/users', query: ['page' => 1, 'itemsPerPage' => 20], headers: ['X-Request-ID' => 'req_123'], timeoutMs: 5000, ); $response = $bridge->request($req);
Hydratation des modèles
Les facades utilisent Symfony\Component\Serializer\Normalizer\NormalizerInterface et DenormalizerInterface pour la sérialisation/désérialisation.
Les modèles du SDK exposent @id via la propriété $iri.
Si vous utilisez vos propres modèles, mappez @id avec #[SerializedName('@id')].
Note technique : Le SDK nécessite que le SerializerInterface implémente aussi NormalizerInterface et DenormalizerInterface (ce qui est le cas avec le Serializer standard de Symfony). Le FacadeFactory vérifie automatiquement ces interfaces au runtime.
API publique
Classes principales
BridgeFacade: appels HTTP bas niveau (GET, GET collection, POST, PUT, PATCH, DELETE, request)FacadeFactory: création deResourceFacade<T>avec hydratation automatiqueResourceFacade<T>: CRUD + collections hydratées (generic type-safe)Collection<T>: items + metadata JSON-LD (totalItems,id,type,context,view,search)
Modèles
Les modèles exposent les propriétés JSON-LD standard :
Item: classe de base avec$iri(@id),$type(@type),$context(@context)- Tous les modèles générés héritent de
Itemou exposent ces propriétés
Paramètres de configuration
Clés principales
base_url: URL de base du service Auth (requis).token: Bearer token optionnel, ajouté si non vide.debug: active les logs debug du bridge HTTP.
defaults (dans obsidiane_auth.yaml)
headers: headers HTTP appliqués à toutes les requêtes (peuvent être surchargés par appel)timeout_ms: timeout en millisecondes (par défaut: aucun)
Options par requête
Toutes les méthodes de ResourceFacade et BridgeFacade acceptent un paramètre HttpCallOptions optionnel :
use Obsidiane\AuthBundle\Bridge\Http\HttpCallOptions; $options = new HttpCallOptions( headers: ['X-Custom-Header' => 'value'], timeoutMs: 5000, // en ms responseType: 'text', ); $users->getCollection([], $options);
responseType: 'text' retourne la réponse brute (string). Par défaut, la réponse est décodée en JSON.
Exemples avancés
Filtrage et pagination
$users = $factory->create('/api/users', UserRead::class); // Pagination $result = $users->getCollection([ 'page' => 2, 'itemsPerPage' => 10, ]); // Filtres $result = $users->getCollection([ 'filters' => [ 'email' => 'user@example.com', 'role' => 'ROLE_ADMIN', ], ]); // Metadata echo $result->totalItems; // Nombre total d'items echo $result->id; // IRI de la collection (@id)
Headers personnalisés
use Obsidiane\AuthBundle\Bridge\Http\HttpCallOptions; $options = new HttpCallOptions( headers: [ 'X-Request-ID' => uniqid(), 'Accept-Language' => 'fr-FR', ], ); $user = $users->get('/api/users/1', $options);
Gestion d'erreurs
use Obsidiane\AuthBundle\Exception\ApiErrorException; try { $user = $users->get('/api/users/999'); } catch (ApiErrorException $e) { // Erreur HTTP (404, 500, etc.) error_log($e->getMessage()); error_log('Status code: ' . $e->getStatusCode()); error_log('Error code: ' . $e->getErrorCode()); }
ApiErrorException expose aussi getDetails() et getPayload() pour inspecter la réponse.
Codes d’erreur (API)
Statuts HTTP exposés par l’API Auth :
| HTTP | Cas principaux | Détails |
|---|---|---|
| 400 | Requête invalide, token invalide | verify-email (id manquant), reset/verify token invalide, invitation sans token (details.token = INVALID_INVITATION). |
| 401 | Non authentifié | me, JWT invalide/expiré, service token invalide, login refusé. |
| 403 | Accès refusé | Origin/Referer non autorisé, endpoints admin sans rôle. |
| 404 | Introuvable | Invitation inconnue, user introuvable, inscription désactivée. |
| 409 | Conflit | Email déjà utilisé, invitation déjà acceptée, bootstrap requis ou déjà fait. |
| 410 | Expiré | Invitation expirée, lien de vérification expiré, reset token expiré. |
| 422 | Validation | Email/mot de passe invalides, champs requis, INVALID_ROLES, confirmation mot de passe. |
| 423 | Verrouillé | Email non vérifié lors du login. |
| 429 | Rate limit | Login, register, invite, invite/complete, password/forgot/reset, setup/admin. |
| 500 | Erreur interne | Échec de reset password non géré (ResetRequestFailedException). |
| 503 | Service indisponible | Échec d’envoi d’email (MailDispatchException). |
Identifiants d’erreurs utiles dans les payloads/validations :
INVALID_INVITATIONINVALID_ROLES
Invitation (règles métiers)
- Un utilisateur déjà vérifié ne peut pas être ré-invité.
- Un utilisateur non vérifié peut être ré-invité : l’email est renvoyé si l’invitation est encore valide, sinon elle est régénérée.
Qualité du code
Le SDK maintient une qualité de code stricte :
- ✅ PHPStan Level 6 : Zero erreur d'analyse statique
- ✅ Types stricts :
declare(strict_types=1)dans tous les fichiers - ✅ Generics :
ResourceFacade<T>,Collection<T>pour type-safety - ✅ Readonly : Classes immuables avec
readonly - ✅ PSR-12 : Standard de code PHP
Troubleshooting
Erreur "Serializer must implement NormalizerInterface"
Si vous obtenez cette erreur, assurez-vous que votre SerializerInterface est bien le Serializer standard de Symfony (pas un mock ou une implémentation custom sans normalizer).
Timeout des requêtes
Par défaut, aucun timeout n'est appliqué. Pour en définir un :
# config/packages/obsidiane_auth.yaml obsidiane_auth: defaults: timeout_ms: 30000 # 30 secondes
Ou par requête :
use Obsidiane\AuthBundle\Bridge\Http\HttpCallOptions; $options = new HttpCallOptions(timeoutMs: 30000); $result = $users->getCollection([], $options);
obsidiane/auth-sdk 适用场景与选型建议
obsidiane/auth-sdk 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 139 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 11 月 15 日, 在 PHP 生态内属于活跃度较高的组件。
我们在过去多个企业项目中使用过 obsidiane/auth-sdk 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 obsidiane/auth-sdk 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 139
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 22
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-11-15