jooservices / laravel-identity
Backend identity lifecycle for Laravel: session authentication, registration, activation, and password reset. No UI.
Requires
- php: ^8.5
- illuminate/auth: ^11.0|^12.0|^13.0
- illuminate/console: ^11.0|^12.0|^13.0
- illuminate/contracts: ^11.0|^12.0|^13.0
- illuminate/database: ^11.0|^12.0|^13.0
- illuminate/http: ^11.0|^12.0|^13.0
- illuminate/session: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
- illuminate/validation: ^11.0|^12.0|^13.0
Requires (Dev)
- laravel/pint: ^1.0
- orchestra/testbench: ^9.0|^10.0|^11.0
- phpmd/phpmd: ^2.13
- phpstan/phpstan: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^11.0|^12.0
- squizlabs/php_codesniffer: ^3.0|^4.0
README
Backend identity lifecycle for Laravel applications: session login/logout, registration, activation, password reset, and profile updates.
Package name: jooservices/laravel-identity
No UI. Controllers, Inertia/Blade pages, and SPA assets stay in the host app. Different products may present identity flows differently; this package only provides services, contracts, events, and Artisan commands.
Principles
- SOLID, DRY, KISS, YAGNI
- Patterns only when justified (Service Layer, Repository, DTO, events)
- Laravel flow:
Controller → FormRequest → Service → Repository → Model - Jobs/Commands orchestrate through Services
- Events dispatch from Services after successful persistence
Install
composer require jooservices/laravel-identity
Publish config (optional):
php artisan vendor:publish --tag=laravel-identity-config
Optional starter migrations (skip if the host already has users / password_reset_tokens):
php artisan vendor:publish --tag=laravel-identity-migrations
Host setup
- Point
laravel-identity.user_modelat your Authenticatable model. - Prefer implementing
IdentityUser(or useHasIdentityActivation) foris_active. - Optionally bind a custom
PasswordPolicyInterface(default is a no-op). - Optionally replace repository bindings.
// config/laravel-identity.php (or env) 'user_model' => App\Models\User::class, 'require_activation' => true,
use Jooservices\LaravelIdentity\Concerns\HasIdentityActivation; use Jooservices\LaravelIdentity\Contracts\IdentityUser; class User extends Authenticatable implements IdentityUser { use HasIdentityActivation; // ... }
Usage (host controller / command)
use Jooservices\LaravelIdentity\Dto\LoginDto; use Jooservices\LaravelIdentity\Services\AuthenticationService; public function store(LoginRequest $request, AuthenticationService $auth): RedirectResponse { $auth->login( new LoginDto( email: $request->email(), password: $request->password(), remember: $request->boolean('remember'), ip: (string) $request->ip(), ), $request, ); return redirect()->intended('/dashboard'); }
use Jooservices\LaravelIdentity\Dto\RegisterUserDto; use Jooservices\LaravelIdentity\Services\UserLifecycleService; $users->register(new RegisterUserDto($name, $email, $password, $ip)); $users->activateUser($email); $users->requestPasswordReset(new RequestPasswordResetDto($email, $ip));
Artisan
php artisan identity:activate-user user@example.com php artisan identity:reset-password user@example.com --password=secret
Host apps may keep product-prefixed wrappers (e.g. xflickr:auth:*) that call the same services.
Events
| Event | When |
|---|---|
UserRegistered |
After register |
UserActivated |
After activate (when previously inactive) |
PasswordResetRequested |
After reset token created (email, plainToken, resetUrl) — host may send email; do not log the token |
PasswordChanged |
After password update |
What is out of scope
- UI / Inertia / Blade / React
- RBAC / policies / teams
- Social OAuth
- Forced email delivery (listen to
PasswordResetRequestedinstead)
Quality
composer test
composer lint
composer check
Standards
Aligned with JOOservices dto package architecture guidance and Laravel best practices (thin controllers, FormRequest validation, service-owned business logic, repository persistence).