paragonie/paseto
Reference PHP implementation of PASETO security tokens (v3/v4): safer alternative to JWT/JWE/JWS with modern crypto. Supports local and public tokens, includes PASERK integration for key serialization/wrapping, and works with Sodium (or sodium_compat).
v3/v4), reducing risk during upgrades. Aligns with Laravel’s modular architecture (e.g., swapping out JWT mid-project).local (encrypted) and public (unencrypted) tokens enable granular use cases (e.g., local for internal APIs, public for stateless auth).config/encryption.php) via symmetric/asymmetric keys, with optional PEM/Sodium support.firebase/jwt or lcobucci/jwt in auth packages (e.g., Sanctum, Passport).Redis) for token storage/validation.auth:api) via custom guards or token parsers.paseto tokens instead of JWTs in sessions or oauth_access_tokens tables).cache()->put('paseto:user123', $token)), with validation on access.KeyRing support (e.g., overlapping keys during transitions). Laravel’s config/keys.php can store multiple keys.v4 tokens prefer Sodium; fallback to sodium_compat adds ~100KB but may impact performance. Test in staging first.Validator rules for footers).v4.local) may impact cookie storage limits.KeyRing be used, or manual key updates in config/encryption.php?v4 tokens against current JWT/JWE for latency (especially with Sodium).auth logging.Illuminate\Contracts\Auth\AccessToken or Illuminate\Auth\Guard implementations to use PASETO.Sanctum\PersonalAccessToken to use PASETO builders/parsers.OAuth2\AccessToken to issue PASETO tokens via custom TokenRepository.ValidatePasetoToken::dispatch($token)) for high-traffic APIs./api/login) with PASETO.config('auth.use_paseto', false)) to toggle between JWT/PASETO.'auth' => [
'default' => 'paseto',
'guards' => [
'api' => [
'driver' => 'token',
'provider' => 'users',
'use_paseto' => true,
],
],
],
paseto_token column alongside token).PasetoJwtAdapter).APP_KEY) can be reused for symmetric PASETO (SymmetricKey).Illuminate\Auth\Middleware\Authenticate to handle PASETO tokens:
public function handle($request, Closure $next) {
if ($request->bearerToken() && config('auth.use_paseto')) {
$token = $this->validatePasetoToken($request->bearerToken());
auth()->setUser($token->getUser());
}
return $next($request);
}
HttpTests to verify token flows (e.g., login, refresh, revocation).config/encryption.php or a secrets manager.PasetoService facade to wrap token creation:
class PasetoService {
public function issueLocal(array $claims): string {
$key = SymmetricKey::fromString(config('paseto.key'));
return Builder::getLocal($key)
->setClaims($claims)
->setExpiration(now()->addHours(1))
->toString();
}
}
PasetoGuard to validate tokens in middleware:
class PasetoGuard extends Guard {
public function validateToken($token) {
$parser = Parser::getLocal(SymmetricKey::fromString(config('paseto.key')))
->addRule(new ValidAt)
->addRule(new IssuedBy(config('app.name')));
return $parser->parse($token);
}
}
paseto_token column to sessions/oauth_access_tokens:
Schema::table('oauth_access_tokens', function (Blueprint $table) {
$table->text('paseto_token')->nullable()->after('token');
});
schedule or a cron job to update KeyRing entries:
// app/Console/Commands/RotatePasetoKeys.php
public function handle() {
$oldKey = SymmetricKey::fromString(config('paseto.old_key'));
$newKey = SymmetricKey::generate();
config(['paseto.key' => $newKey->raw()]);
$this->updateKeyRing($oldKey, $newKey);
}
paragonie/paseto for breaking changes (e.g., PHP 8.2+ features). Use Laravel’s composer.json scripts for testing:
"scripts": {
"test:paseto": "php artisan paseto:test"
}
auth logging to include PASETO events (e.g., paseto.validated, paseto.expired).v3.local vs v4.public).v4 tokens.Parser (e.g., FooterJSON max depth).auth section, including:
KeyRing configurations for multi-tenant apps.v4.local tokens are ~1KB; ensure API gateways (e.g., Nginx) handle headers up to 4KB.throttle middleware to limit token validation attempts (e.g., brute-force attacks on public tokens).| **Failure
How can I help you explore Laravel packages today?