dskripchenko/laravel-admin
A Laravel admin panel package for quickly building CRUD interfaces and managing application data. It provides resource-based screens, forms, tables, filters, and admin routing to speed up backend management and configuration.
This package wires Laravel session authentication into a SPA shell plus an API surface, with sign-out coordinated against identity providers. The v1.51.1 patch doesn't change how you install or call it, but it changes what you should verify first.
Minimal path:
composer require, then publish the package config and migrations if the release line ships any session tables). The important knobs for day-to-day work are the cache store used for auth bookkeeping, the session lifetime, and the route prefixes for the API, bootstrap, and shell endpoints.Auth\EndedSessions registry lives in the cache for the lifetime of the session. On a single box array works by accident; on anything with more than one PHP process — Octane, multiple app servers, blue/green deploys — you need Redis, database, or memcached, and it must be the same store the web and API nodes read. This is the first thing to check in config/cache.php and any per-environment overrides.Where to look first in the source: the sign-out action, the Auth\EndedSessions class, and the middleware or guard that consults it. The three call sites named in the notes — API, bootstrap, shell — are the three places the check is applied, so any custom route you add that resolves the session outside those groups is your responsibility.
Treat ended-session tracking as part of your auth contract. The registry records the ended session id for the remainder of the session's lifetime so an in-flight request carrying the old id is signed out and handed a fresh session rather than writing the old one back. Don't build anything that depends on a session id being reusable after sign-out — it isn't, and that's now enforced across all three entry points.
Multi-tab and multi-device flows. The classic failure mode is tab A signing out while tab B has a poll in flight. With this fix, tab B's request is rejected and gets a new empty session, which is usually what you want: the next poll returns unauthenticated and your front end redirects to login. Make sure your SPA treats a 401 on a background request as "redirect to login", not "retry with the same credentials", or you'll produce a redirect loop against a session that no longer exists.
Identity-provider sign-out. Since 1.51.0 a sign-out at the IdP reloads the page, which is what made the race visible. If you implement single logout, do the local sign-out first (so the ended-session marker is written) and only then redirect to the IdP. Reversing that order leaves a window where the local session is still valid while the user believes they're logged out.
Background jobs and queued work. Anything that mutates session state from a queue worker won't go through the HTTP middleware, so the ended-session check won't run. Keep session-affecting logic in request-handling code; let jobs operate on user ids, not sessions.
Testing pattern. Write a feature test that starts a request against a protected route, signs the user out, then completes the first request and asserts it comes back unauthenticated with a fresh session rather than the old cookie. This is hard to express with a single test client, so use two clients or a fake cache you can inspect. Asserting on the contents of the ended-session store directly is often the simplest signal that the marker was written.
Custom endpoints. If you add routes that resolve the guard outside the package's API/bootstrap/shell groups, they bypass the check. Either put them inside the existing middleware stack or add the equivalent guard yourself.
SESSION_LIFETIME means a larger set of markers in cache and a longer window in which an old cookie is refused. Shortening it speeds cleanup but narrows the protection window; if your SPA keeps requests open for a long time (long polls, SSE), size it to your slowest request.php artisan cache:clear during a deploy wipes the ended-session markers, reopening the race until sessions naturally expire. If you flush cache on deploy, prefer a versioned cache prefix rather than a full flush, or accept the brief window.composer update is enough; just confirm the shared cache store before you ship, since on single-process dev setups the fix looks like a no-op.How can I help you explore Laravel packages today?