vouchedfor/token-bundle
vouchedfor/token-bundle is a Symfony bundle for token-based authentication, offering configurable token generation and validation services that integrate with existing user providers. It suits legacy or lightweight apps needing simple API access tokens without a full OAuth stack.
First, calibrate expectations: despite the Laravel framing, vouchedfor/token-bundle is a Symfony bundle — the -bundle suffix and *Bundle.php class are the tell. There is no Laravel service provider, no facade, no package auto-discovery. In a Laravel app you will not composer require your way to working tokens; you will either (a) port the token lifecycle into a Laravel-native service, or (b) if you also run a Symfony application, install it there and call it behind an interface.
Read the repository in this order:
composer.json — PHP and symfony/* constraints. This one file decides whether the code is installable on your stack at all. With one star and zero dependents, expect constraints pinned to an era of Symfony (2.x/3.x) that modern PHP 8.2+ will reject.DependencyInjection/*Extension.php — the getAlias() return value is your real config root key, and load() shows which services actually exist. This is the map of the package.Pick the smallest possible first use case: issue a token, store it, validate it once, expire it. Email verification or password reset. Do not start with API authentication — the bundle almost certainly does not do request-level auth for you anyway.
If you are porting to Laravel (the realistic path):
TokenIssuer / TokenValidator and bind an implementation in a service provider. Call sites then never depend on the ported code, so swapping in Sanctum or a hand-rolled implementation later is a one-line change.tokens table with tokenable_id, tokenable_type, token_hash, purpose, expires_at, consumed_at. Store the hash, never the plaintext; return plaintext to the caller exactly once, at creation.bin2hex(random_bytes(32)) for the token, hash_equals($storedHash, hash('sha256', $presented)) for validation. Constant time, no early-exit comparison.sendEmailVerification() or beginPasswordReset() on the model (or an observer) reads far better than TokenManager::create($user, 'reset') scattered through HTTP handlers.(tokenable, purpose). A unique constraint on that tuple plus updateOrCreate eliminates a whole class of "which link is valid" confusion.->daily() prune of expired rows, and a TokenConsumed event for rate limiting or analytics.If you genuinely have a Symfony app and can install it: register in config/bundles.php, add a YAML block under the extension alias, inject the token service into your controller or authenticator. Standard Symfony idioms apply — a service alias or compiler pass swaps the generator without editing vendor code.
Integration tip: push issuance into queued jobs or event listeners so the HTTP request does not block on token writes, and so a failed mail send does not leave an orphaned row.
$container->get(...) idioms into Laravel's is manual work — budget for it up front.composer require vouchedfor/token-bundle --dry-run before planning around it. If it fails, copy the two or three relevant classes into app/Support rather than fighting Composer.rand(), mt_rand(), uniqid(), or md5(time()). Any of these means generation is not cryptographically sound and must be replaced wholesale. In a 1-star, 0-dependent package this is the most likely defect.consumed_at-style logic is absent, add it yourself — do not assume the bundle handles replay.getAlias(), often the short form (token), not vouched_for_token. If your YAML config is silently ignored, that is why.NOTICE file for attribution.debug:container --tag=... plus the profiler's service panel show what is actually registered. In a port, log the token id and hash (never the plaintext) at issue/validate/prune so lifecycle bugs are visible.services.yaml alias in Symfony, $this->app->bind() in Laravel — rather than editing vendor code.How can I help you explore Laravel packages today?