gusmanwidodo / auth-kit-credentials
Identifier + password login for Auth-Kit: register, login (email/phone/username + password), and forgot/reset password. Flexible single-identifier model, hashed passwords, single-use hashed reset tokens.
Package info
github.com/gusmanwidodo/auth-kit-credentials
pkg:composer/gusmanwidodo/auth-kit-credentials
Requires
- php: ^8.3
- gusmanwidodo/auth-kit: ^0.1
- illuminate/contracts: ^12.0
- illuminate/database: ^12.0
- illuminate/support: ^12.0
Requires (Dev)
- orchestra/testbench: ^10.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
README
Identifier + password authentication for Auth-Kit: register, login (email / phone / username + password), and forgot / reset password. This is the fundamental credential login the ecosystem was missing.
Features
- Register with a flexible identifier (email / phone / username) + password.
- Login with any configured identifier type; passwords hashed via Laravel
Hash(bcrypt/argon per your app's config). - Forgot / reset password with single-use, expiring, hashed reset tokens.
- Timing-safe login — unknown identifiers still perform a hash comparison so response timing does not reveal whether an account exists.
- No user enumeration —
forgot-passwordresponds identically whether or not the identifier exists. - Composes with the rest of Auth-Kit: a registered subject can then get roles (permissions), join organizations/teams, and link social accounts.
See ADR 006.
Requirements
- PHP
^8.3 gusmanwidodo/auth-kit^0.1- Laravel 12
Installation
composer require gusmanwidodo/auth-kit-credentials php artisan migrate php artisan vendor:publish --tag=auth-kit-credentials-config
Endpoints
| Method | URI | Body |
|---|---|---|
| POST | /auth-kit/credentials/register |
{ identifier, password, type? } |
| POST | /auth-kit/credentials/login |
{ identifier, password, type? } |
| POST | /auth-kit/credentials/forgot-password |
{ identifier, type? } |
| POST | /auth-kit/credentials/reset-password |
{ identifier, token, password, type? } |
type is one of the configured identifier_types (default email; also
phone, username). Omit it to use the default.
Usage
use Gusmanwidodo\AuthKitCredentials\CredentialManager; $auth = app(CredentialManager::class); // Register (email by default) $auth->register('user@example.com', 'secret123'); // ...or with an explicit type $auth->register('+628123456789', 'secret123', 'phone'); $auth->register('gusman', 'secret123', 'username'); // Login (throws InvalidCredentialsException on failure) $credential = $auth->login('user@example.com', 'secret123'); // Forgot -> returns a plaintext token for YOU to deliver by email/SMS // (only the hash is stored). Returns null for an unknown identifier. $token = $auth->forgot('user@example.com'); // Reset with the token $auth->reset('user@example.com', $token, 'newSecret123');
Linking a subject (optional)
By default a credential stores its own identity. To attach it to your User model,
resolve the subject in a before:credentials.register hook:
public function beforeHooks(): array { return [ 'credentials.register' => function ($ctx) { $user = User::create(['email' => $ctx->get('identifier')]); $ctx->set('subject_type', User::class)->set('subject_id', $user->id); }, ]; }
login() then returns the linked subject_type / subject_id, which your app
uses to Auth::login() the user.
Hooks
| Event | When | Notes |
|---|---|---|
before:credentials.register |
Before creating a credential | Set subject_type/subject_id to link |
after:credentials.register |
After creation | — |
before:credentials.login |
Before returning success | Set allow=false to veto (e.g. locked account) |
after:credentials.login |
On successful login | — |
after:credentials.forgot |
After a reset token is issued | Deliver the token here if you prefer |
after:credentials.reset |
After a successful reset | — |
Security notes
- Passwords hashed with Laravel
Hash(never stored plaintext;password_hashis hidden from serialization). - Reset tokens are random 64-char strings; only their hash is stored, and
they are single-use and time-limited (
reset_ttl, default 1 hour). - Login is timing-safe against unknown identifiers.
forgot-passwordnever reveals whether an identifier exists.- Password delivery (reset email/SMS) is the app's responsibility.
Config
config/auth-kit-credentials.php:
'identifier_types' => ['email', 'phone', 'username'], 'default_identifier_type' => 'email', 'lowercase_types' => ['email', 'username'], 'min_password_length' => 8, 'reset_ttl' => 3600, // seconds
Developing against a local core
composer config repositories.auth-kit path ../auth-kit composer require gusmanwidodo/auth-kit:@dev composer install composer test # 18 tests
Note:
composer require :@devrewrites this composer.json to@dev. Revert thegusmanwidodo/auth-kitconstraint to^0.1and remove anyrepositoriesblock before committing/tagging a release.
License
MIT © Gusman Widodo. See LICENSE.