Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Larke Admin Laravel Package

lake/larke-admin

Larke Admin is a Laravel-based admin panel and rapid development framework with authentication, RBAC permissions, menu management, CRUD tools, and a Vue frontend, helping PHP developers build back-office systems and APIs quickly.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install and confirm framework compatibility. The package targets Laravel (check composer.json for the supported major versions before committing — it has moved forward over time). Install with:

composer require lake/larke-admin

2. Publish and install. The package ships a service provider that auto-registers routes; you then publish config, migrations, and seed data. Rather than guessing command names, enumerate them once:

php artisan list | grep -i larke
php artisan vendor:publish --provider="Lake\LarkeAdmin\LarkeAdminServiceProvider"
php artisan migrate

Seed the base admin user, groups, and rule/menu rows — the seeded super-admin account is what you log in with on the first request. Change that password immediately.

3. Configure the JWT guard. This is the step people skip. Declare a dedicated guard in config/auth.php (driver jwt, provider pointing at the package's admin model) plus a matching providers entry. Do not reuse your application's user guard — admin and app-user tokens must not be interchangeable.

4. Set the secret. Generate the JWT secret (php artisan jwt:secret if the package's JWT layer uses the standard command, otherwise set it via the package config) and verify it is not regenerated on every deploy — a rotating secret logs every admin out and produces confusing 401s.

5. First end-to-end call. Log in, capture the token, then call an authenticated endpoint:

curl -X POST https://app.test/admin/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"..."}'

curl https://app.test/admin/auth/info -H "Authorization: Bearer <token>"

Where to look first: the published config file (route prefix, middleware group, guard name, JWT TTL), then the package's route definitions — those are the authoritative list of endpoints and the permission slug attached to each. Read the migrations next; the RBAC model is admin → admin_group → admin_rule, and understanding that join is the key to everything else.

Implementation Patterns

Keep admin and app auth as two separate worlds. Two guards, two route groups, two token lifetimes. Register the admin routes under the package's prefix with its middleware group, and leave your customer-facing API on auth:sanctum or whatever you already use. Mixing them is the single most common source of "my token works here but not there."

Follow the package's response envelope. The package returns a consistent JSON shape (code/message/data) and its frontend expects it. When you add controllers, extend the package's base controller or use its response helpers rather than returning raw response()->json(), otherwise your custom endpoints will break the shared HTTP client on the Vue side.

Route everything through the permission middleware. Each admin endpoint should carry a rule slug; the middleware maps the slug to the admin_rule table via the caller's group. When you add a feature, you add a rule row and attach the slug — the second half is what people forget, producing 403s that look like auth bugs.

Menu tree as configuration, not code. Menus live in the database and are returned as a tree for the frontend to render. If you're building the frontend yourself, consume that endpoint and drive your router/sidebar from it; don't hardcode nav items, or the permission/menu model becomes decorative.

Extend by publishing, not forking. Publish the config and route file, then point your own controllers at the same middleware group. Subclass the package's controllers for CRUD you want to customize (extra validation, service-layer calls, events) and override container bindings where the package allows it. Fork only if you need to change the RBAC resolution itself.

Hook lifecycle via events, not controller edits. The package dispatches events around admin actions (login, CRUD writes, and so on). Prefer registering listeners in your own EventServiceProvider over patching package controllers — it survives upgrades and keeps side effects (notifications, cache busts, external syncs) out of the CRUD path. Inventory the events you actually listen to and write that list down; the package has historically renamed them between releases (see Gotchas).

Separate a service layer for business logic. The package's controllers are thin CRUD. Anything domain-specific (approval flows, cross-table writes, external calls) belongs in your own services so it stays testable and so a package upgrade doesn't wipe it out.

Use the operation log as an audit trail. The package records admin actions; treat it as your audit log and make sure your custom endpoints either go through the same logging path or write their own entries. This is usually a compliance requirement and retrofitting it later is painful.

Integration tip: put admin routes in their own route file loaded by the provider, and add rate limiting to the login endpoint specifically — an unthrottled admin login is a brute-force target.

Gotchas and Tips

Event names are not a stable API. Release 2.2.0 renamed part of the package's events. This is a silent breaking change: listener classes, $listen maps, queued job payloads, and any string references in tests will simply stop firing — no exception, no deprecation notice, just handlers that never run. Before upgrading, grep your codebase for the event classes you reference, diff them against the new release's Event/Events directory, and re-run your integration tests with logging on the listeners. If you listen to a lot of them, wrap the mapping behind your own thin adapter class so a rename is a one-file change.

Upgrade procedure for point releases. Even a one-line changelog can carry renames. Pin the version, read the changelog and the diff of the Event, Http, and config directories, then upgrade in a branch and smoke-test the flows that depend on the changed area. Treat every 2.x bump as potentially breaking until proven otherwise.

401 vs 403 tells you where to look. 401 = missing/expired/invalid token, or the guard isn't resolving the admin model. 403 = authenticated but the rule slug isn't granted to that admin's group. Conflating these wastes hours.

Permission caching. RBAC rules are cached. After editing rules, groups, or menus in the database, clear the cache or your changes appear to do nothing. Wire the cache clear into any admin UI you build for managing permissions, and be aware that multi-server deployments need a shared cache store.

File cache breaks token invalidation. Logout/blacklist relies on a cache backend that supports it properly. Use Redis (or another shared store) in production; the file driver gives you inconsistent blacklist behaviour, especially behind a load balancer.

Guard misconfiguration presents as "Unauthenticated" on every request, even with a valid token. Check that auth.php has the guard, the provider, and the correct model — and that the package config points at the same guard name.

Super-admin bypass will fool you during testing. The seeded root account typically skips permission checks. Test permission logic with a non-super admin account in a restricted group, or you'll ship a feature nobody else can use.

Route caching and closures. If you publish the route file, avoid closures — php artisan route:cache will fail or silently drop them, and it only shows up in production after a deploy.

Migration collisions. If you already have an admins table or an existing user model, check the table names and any prefix setting before running migrate. On an existing database, publish and edit the migration rather than running it blind.

Re-publishing overwrites your edits. Publish config and migrations in separate steps, keep them in version control, and never run vendor:publish --force on a server. Note that vendor:publish will not update already-published files on package upgrades — diff the package's config against yours after every version bump.

JWT TTL and clock skew. Short default TTLs plus container clock drift produce tokens that expire immediately. Verify TTL settings and use the refresh endpoint rather than extending TTL to something unreasonable.

Stability and bus factor. Single-maintainer package with a small ecosystem — pin the version in composer.json, read the changelog before upgrading, and if this is going into something long-lived, budget for the possibility of vendoring the package. Apache-2.0 means forking is legally straightforward; treat that as your escape hatch, not your plan.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
unabomber/timezone
delatbabel/contacts
astritzeqiri/g-recaptcha
kevinongko/laravel-genode
developeruz/laravel-analytics
robbiep/afterthedeadline
frankkessler/incontact-laravel-oauth2-rest
jlxh/laravel-userlog
davidmgilo/timetables
qylinfly/role-permission
reflect-digital/conduit
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr