PHPackages                             preflow/auth - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. preflow/auth

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

preflow/auth
============

Preflow auth — pluggable guards, session auth, API tokens, password hashing

v0.13.1(1mo ago)0302MITPHPPHP &gt;=8.4

Since Apr 12Pushed 1mo agoCompare

[ Source](https://github.com/getpreflow/auth)[ Packagist](https://packagist.org/packages/preflow/auth)[ RSS](/packages/preflow-auth/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (4)Versions (17)Used By (2)

Preflow Auth
============

[](#preflow-auth)

Pluggable authentication for Preflow applications. Session-based login, API token guards, password hashing, and PSR-15 middleware.

Installation
------------

[](#installation)

```
composer require preflow/auth
```

Requires `preflow/core` and `preflow/data`.

What it does
------------

[](#what-it-does)

- Pluggable guard system — session and bearer token guards ship as defaults, implement `GuardInterface` for custom auth
- Session management with CSRF protection (both in `preflow/core`)
- Password hashing via `password_hash()` / `password_verify()` with transparent rehash support
- PSR-15 middleware for route-level auth (`AuthMiddleware`) and guest-only pages (`GuestMiddleware`)
- Template functions: `auth_user()`, `auth_check()`, `csrf_token()`, `csrf_field()`, `flash()`
- Auto-discovered by `Application::boot()` when `config/auth.php` exists

Configuration
-------------

[](#configuration)

`config/auth.php`:

```
return [
    'default_guard' => 'session',

    'guards' => [
        'session' => [
            'class' => Preflow\Auth\SessionGuard::class,
            'provider' => 'data_manager',
        ],
        'token' => [
            'class' => Preflow\Auth\TokenGuard::class,
            'provider' => 'data_manager',
        ],
    ],

    'providers' => [
        'data_manager' => [
            'class' => Preflow\Auth\DataManagerUserProvider::class,
            'model' => App\Models\User::class,
        ],
    ],

    'password_hasher' => Preflow\Auth\NativePasswordHasher::class,

    'session' => [
        'lifetime' => 7200,
        'cookie' => 'preflow_session',
        'secure' => true,
        'httponly' => true,
        'samesite' => 'Lax',
    ],
];
```

User model
----------

[](#user-model)

Implement the `Authenticatable` interface. Use `AuthenticatableTrait` for the common case:

```
use Preflow\Auth\Authenticatable;
use Preflow\Auth\AuthenticatableTrait;
use Preflow\Data\Model;
use Preflow\Data\Attributes\{Entity, Id, Field};
use Preflow\Data\Transform\JsonTransformer;

#[Entity(table: 'users', storage: 'default')]
final class User extends Model implements Authenticatable
{
    use AuthenticatableTrait;

    #[Id] public string $uuid = '';
    #[Field(searchable: true)] public string $email = '';
    #[Field] public string $passwordHash = '';
    #[Field(transform: JsonTransformer::class)] public array $roles = [];
    #[Field] public ?string $createdAt = null;
}
```

The trait assumes `$uuid`, `$passwordHash`, and `$roles` properties. Override methods if your schema differs.

API
---

[](#api)

### Guards

[](#guards)

```
// Resolve from container (after boot)
$auth = $container->get(AuthManager::class);

$guard = $auth->guard();          // default guard
$guard = $auth->guard('token');   // named guard

$user = $guard->user($request);   // resolve user from request
$guard->login($user, $request);   // establish session
$guard->logout($request);         // invalidate session
$guard->validate(['email' => $email, 'password' => $password]); // check credentials
```

### SessionGuard

[](#sessionguard)

Stores user ID in session key `_auth_user_id`. Regenerates session on login (session fixation prevention). Invalidates session on logout.

### TokenGuard

[](#tokenguard)

Reads `Authorization: Bearer ` header. Looks up SHA-256 hashed token in `user_tokens` table. Stateless — `login()` and `logout()` are no-ops.

```
// Create a token
$plain = PersonalAccessToken::generatePlainToken();

$token = new PersonalAccessToken();
$token->uuid = bin2hex(random_bytes(16));
$token->tokenHash = PersonalAccessToken::hashToken($plain);
$token->userId = $user->getAuthId();
$token->name = 'api-key';
$dm->save($token);

// Return $plain to the user (only shown once)
```

### Password hashing

[](#password-hashing)

```
$hasher = $container->get(PasswordHasherInterface::class);

$hash = $hasher->hash('secret');
$hasher->verify('secret', $hash);      // true
$hasher->needsRehash($hash);           // false (current algorithm)
```

### Middleware

[](#middleware)

Protect routes with `#[Middleware]` attributes:

```
use Preflow\Routing\Attributes\{Route, Get, Middleware};
use Preflow\Auth\Http\AuthMiddleware;

#[Route('/dashboard')]
#[Middleware(AuthMiddleware::class)]
final class DashboardController
{
    #[Get('/')]
    public function index(ServerRequestInterface $request): ResponseInterface
    {
        $user = $request->getAttribute(Authenticatable::class);
        // ...
    }
}
```

`GuestMiddleware` redirects authenticated users away (for login/register pages).

### Templates

[](#templates)

```
{% if auth_check() %}
    Welcome, {{ auth_user().email }}

        {{ csrf_field() }}
        Logout

{% endif %}

{% set error = flash('error') %}
{% if error %}
    {{ error }}
{% endif %}
```

### CSRF helpers

[](#csrf-helpers)

> **Breaking change in v0.11:** `csrf_token()` now returns the raw token string. Use `csrf_field()` for forms.

FunctionReturns`csrf_token()`Raw token string — useful for `fetch()` headers or meta tags`csrf_field()`Complete `` element```
{# In a form #}
{{ csrf_field() }}

{# In a fetch() call #}

```

Any template that previously used `{{ csrf_token()|raw }}` must be updated to `{{ csrf_field() }}`.

Custom guards
-------------

[](#custom-guards)

Implement `GuardInterface`:

```
use Preflow\Auth\{GuardInterface, Authenticatable};
use Psr\Http\Message\ServerRequestInterface;

final class LdapGuard implements GuardInterface
{
    public function user(ServerRequestInterface $request): ?Authenticatable { /* ... */ }
    public function validate(array $credentials): bool { /* ... */ }
    public function login(Authenticatable $user, ServerRequestInterface $request): void { /* ... */ }
    public function logout(ServerRequestInterface $request): void { /* ... */ }
}
```

Register in `config/auth.php` under `guards`.

Testing
-------

[](#testing)

```
use Preflow\Testing\AuthTestHelpers;

final class DashboardTest extends TestCase
{
    use AuthTestHelpers;

    public function test_dashboard_requires_auth(): void
    {
        $user = new TestUser(uuid: 'u1', roles: ['admin']);
        $request = $this->actingAs($user, $this->createRequest('GET', '/dashboard'));
        // $request now has Authenticatable attribute set
    }
}
```

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance89

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

16

Last Release

56d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/6d8b54efbc79683c32645e3fa8d3590037fa003963a16e0ed989104c6f4a2723?d=identicon)[smyr](/maintainers/smyr)

---

Top Contributors

[![smeyerme](https://avatars.githubusercontent.com/u/1925560?v=4)](https://github.com/smeyerme "smeyerme (11 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/preflow-auth/health.svg)

```
[![Health](https://phpackages.com/badges/preflow-auth/health.svg)](https://phpackages.com/packages/preflow-auth)
```

###  Alternatives

[kartik-v/yii2-password

Useful password strength validation utilities for Yii Framework 2.0

761.2M17](/packages/kartik-v-yii2-password)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
