Servisné tokeny
Servisné tokeny sú krátkodobé HS256 JWT, ktorými sa jedna backendová služba preukazuje druhej. Každý má scope = service a je viazaný na pomenovaného odosielateľa (iss) a príjemcu (aud):
use RoundlyConsulting\Jwt\Facades\Jwt;
$token = Jwt::services()->issue('target-service')->token;
// Or attach one to an outbound internal HTTP call:
Jwt::services()->request('target-service')
->post('https://target.internal/endpoint', [...]);
// On the receiving side, behind `auth:service` (a `service-jwt` guard):
Jwt::services()->claims()?->string('iss'); // the calling serviceVydaný token nesie iss (service.issuer), aud (argument, inak service.audience), iat, nbf, exp, jti a scope = service a platí service.ttl sekúnd — predvolene 60. Vydanie bez audience alebo s prázdnym vlastným vydavateľom vyhodí ServiceAuthMisconfigured: token bez adresáta či anonymný token nikdy nevznikne.
Doplnkové claimy
issue() prijme voliteľné pole doplnkových claimov — napríklad kontext pre worker, ktorý koná v mene držiteľa. Registrované názvy sa odmietnu, nie potichu prepíšu:
// Extra, non-registered claims travel with the token:
Jwt::services()->issue('notifications', ['job' => 'nightly-sync']);
// A registered name (iss, aud, iat, nbf, exp, jti, scope, sub,
// permissions, tv, email, email_verified) is rejected, not merged:
Jwt::services()->issue('notifications', ['aud' => 'billing']); // throws ServiceAuthMisconfiguredOdchádzajúce volania
Jwt::services()->request() a authenticate() pripoja čerstvo vydaný token ako bearer k HTTP klientovi Laravelu:
use Illuminate\Support\Facades\Http;
use RoundlyConsulting\Jwt\Facades\Jwt;
// A new pending request already carrying a fresh token for the audience.
$response = Jwt::services()->request('notifications')
->post('https://notifications.internal/send', $payload);
// Or attach a token to an existing pending request.
$pending = Http::baseUrl('https://notifications.internal')->acceptJson();
$response = Jwt::services()->authenticate($pending, 'notifications')->post('/send', $payload);- request(?string $audience = null) — nový PendingRequest s už pripojeným čerstvým tokenom.
- authenticate(PendingRequest $request, ?string $audience = null) — pripojí čerstvý token k existujúcemu requestu.
Výber režimu tajomstva
Pri jednom zdieľanom tajomstve je jediným dôkazom jeho vlastníctvo — ktokoľvek ho má, môže vydať token s ľubovoľným iss, takže zoznam povolených vydavateľov je len označenie, nie autentifikácia:
# Shared mode: one secret for the whole mesh (openssl rand -base64 48).
SERVICE_JWT_SECRET=<secret>Pre skutočnú identitu služieb dajte každej službe vlastné tajomstvo. Overovač vyberie tajomstvo podľa iss v tokene — podobne ako pri kid — takže podvrhnutý iss vyberie tajomstvo, ktorému podpis nezodpovedá, a jedno uniknuté tajomstvo už nestačí na vydávanie sa za celú sieť služieb:
# Per-issuer mode (recommended): overrides SERVICE_JWT_SECRET when set.
SERVICE_JWT_SECRETS="billing:<secret>,api:<secret>"V tomto režime musí byť vlastný service.issuer vydávajúcej aplikácie v mape, inak vydanie vyhodí ServiceAuthMisconfigured. Neznámy prichádzajúci vydavateľ sa overí voči pevnému fiktívnemu tajomstvu a odmietne ako InvalidSignature — rovnaká práca aj chyba ako pri zlom podpise, takže nastavené názvy vydavateľov sa nedajú zistiť.
Prijímanie servisných tokenov
Prichádzajúce tokeny musia byť adresované vlastnému názvu tejto služby — jwt.service.name, ktorý nastavíte cez JWT_SERVICE_NAME. Ak chýba, použije sa config('app.service') a potom slug z APP_NAME; nastavte ho preto explicitne na stabilný identifikátor, inak by premenovanie aplikácie zmenilo názov služby a rozbilo všetkých volajúcich:
# This service's own name — the aud every inbound service token must carry.
JWT_SERVICE_NAME=notifications
# Optional inbound allow-list; empty accepts any issuer.
JWT_SERVICE_ISSUERS=billing,apiOverenie vyžaduje platný HS256 podpis, scope = service, aud zhodné s názvom služby, neprázdny iss a — ak je nastavené service.issuers — iss z tohto zoznamu. Zapojte guard a čítajte volajúcu službu:
// config/auth.php
'guards' => [
'service' => ['driver' => 'service-jwt'],
],
// routes
Route::middleware('auth:service')->post('/send', SendController::class);
// inside the controller
$caller = $request->user('service'); // ServiceIdentity
$caller->getAuthIdentifier(); // the calling service's 'iss'
$caller->claims(); // the full Claims bag
Jwt::services()->claims(); // the same claims, through the facade
auth()->guard('service')->payload(); // …or straight from the guardAlebo overte explicitne:
$claims = Jwt::services()->verify($jwt);Chýbajúce, príliš krátke, z jedného opakovaného bajtu zložené alebo PEM tajomstvo, prípadne chýbajúci názov služby, vyhodí ServiceAuthMisconfigured — 500, nikdy tiché 401.
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.