NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky
JWT for Laravel

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 service

Vydaný 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 ServiceAuthMisconfigured

Odchá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,api

Overenie 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 guard

Alebo 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 kryptomien

Odoslaní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.