konekt/user
Konekt User is a Laravel package for complete user management, covering authentication, registration, login, password reset, profiles, addresses, and user CRUD with configurable models and integration into the Konekt/Concorde ecosystem.
konekt/user is not a standalone auth starter — it's a Concord module. Almost everything (model binding, migrations, config merge) happens through konekt/concord, so installing the package alone gets you nothing until the module is registered. Plan for two dependencies, not one.
Minimal setup:
composer require konekt/user
// config/concord.php
return [
'modules' => [
Konekt\User\Providers\ModuleServiceProvider::class,
// ... other konekt modules (address, customer, contact)
],
];
Then run the module migrations (Concord loads them from the package — check the provider for $migrations/loadMigrationsFrom rather than publishing by reflex) and confirm the users table exists.
Read these three files first, in this order:
src/Providers/ModuleServiceProvider.php — the $models array tells you which contracts bind to which concretes, and whether any config/routes/migrations are registered.src/Models/User.php — the actual field list, casts, traits, and any activate() / isActive() / type helpers. This is the whole surface area; the package is small.src/Contracts/User.php — the interface you should type-hint against everywhere.First use case: get a guard working against the module's model, then create a user and log in.
// config/auth.php
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => Konekt\User\Models\User::class, // or your subclass
],
],
use Konekt\User\Contracts\User;
$user = app(User::class)->create([
'name' => 'Ada',
'email' => '[email protected]',
'password' => bcrypt('secret'),
]);
Auth::login($user);
Note the app(Contract::class) idiom — Concord binds interfaces to fresh model instances, and it's the sanctioned way to get a model without hard-coding the class.
Type-hint contracts, never concrete models. Every Konekt\User\Models\User reference in your app is a future refactor. app(User::class) and app(User::class)->newQuery() keep you swappable.
Subclassing the User model is the expected customization path. Create your own model extending the packaged one, then re-register the binding inside your module provider (or override the Concord model map) rather than editing vendor files:
namespace App\Models;
class User extends \Konekt\User\Models\User
{
public function team() { return $this->belongsTo(Team::class); }
}
Keep the users table name and the contract implementation intact, otherwise Concord's bindings and any package code doing instanceof checks will break.
User types (if present in your version) are a separate model referenced by type_id. Treat them as seeded reference data, not free-text: create a seeder that inserts the types you need, and gate behavior on the type slug rather than on raw IDs.
Compose with sibling Konekt modules. The real value appears when konekt/customer, konekt/contact, or konekt/address are present: a customer has a user, a user has a person/profile. Model those relationships in your app-level module so package upgrades don't fight you.
Registration flow. Because the package ships persistence, not UI, wire it into your own controller/FormRequest:
public function store(StoreUser $request)
{
$user = app(User::class)->create($request->validated());
$user->activate(); // if the package exposes an active flag
event(new Registered($user));
return redirect()->route('login');
}
Testing. Concord makes bindings swappable, so $this->instance(User::class, $fake) or a factory on your subclass works cleanly. Write a factory against your subclass, not the vendor model.
composer.json constraints before committing. Packages in this family target specific Laravel major versions. If you're on Laravel 10/11, verify the illuminate/* and konekt/concord constraints resolve before you design around it; a failed resolution here is common and not a quick fix.ModuleServiceProvider entry in config/concord.php produces the confusing symptom of "class not found / table doesn't exist" rather than a clear error. That's the first thing to check.is_active-style boolean defaulting to false, Auth::attempt() will fail with generic invalid-credentials errors while the password is perfectly correct. Log the reason in your attemptWhen/custom guard, and always call activate() on registration.config/konekt/user.php → config('konekt.user.*')). Model swap keys are the extension point; publish only if you need to see the defaults, and note that publishing freezes those defaults at install time.Authenticatable. If the packaged model or contract lags behind what Illuminate\Contracts\Auth\Authenticatable expects in your Laravel version (e.g. getAuthPasswordName()), you'll get a fatal only at login time — a strong argument for your own subclass where you can add the method without touching vendor code.How can I help you explore Laravel packages today?