PHPackages                             pictastudio/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. pictastudio/auth

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

pictastudio/auth
================

Opinionated API authentication and authorization package for Laravel Sanctum with Spatie roles and permissions.

v0.1.7(2mo ago)015[1 PRs](https://github.com/pictastudio/auth/pulls)MITPHPPHP ^8.4CI passing

Since Feb 25Pushed 1mo agoCompare

[ Source](https://github.com/pictastudio/auth)[ Packagist](https://packagist.org/packages/pictastudio/auth)[ Docs](https://github.com/pictastudio/auth)[ GitHub Sponsors]()[ RSS](/packages/pictastudio-auth/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (8)Dependencies (24)Versions (10)Used By (0)

pictastudio/auth
================

[](#pictastudioauth)

[![Latest Version on Packagist](https://camo.githubusercontent.com/2c2c4c57652eff09c886c06bdfabf7bc19ba41be54cbeecfe063f77f671ba9e9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f706963746173747564696f2f617574682e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/pictastudio/auth)[![Total Downloads](https://camo.githubusercontent.com/a30fd73f42493a0058be6dc7035e17474c662d0036417c4ef888e23c48db1bd9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f706963746173747564696f2f617574682e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/pictastudio/auth)

Opinionated API authentication and authorization for Laravel using Sanctum and Spatie roles/permissions.

Features
--------

[](#features)

- Common API auth routes: register, login, logout, current user, forgot/reset password, email verification.
- Dual-mode Sanctum authentication:
    - Stateful cookie/session auth for first-party frontend requests.
    - Bearer token auth for third-party API consumers.
- Config-driven permission generation with pattern `{model}:{action}`.
- Config-driven role bootstrap with defaults:
    - `root` (all permissions)
    - `admin` (all permissions)
    - `user` (no permissions assigned by default)
- Global helper `auth_authorize(...)` to run authorization checks from anywhere.
- User model trait to bootstrap Sanctum + Spatie integration quickly.

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

[](#installation)

```
composer require pictastudio/auth
```

### Install Auth

[](#install-auth)

```
php artisan auth:install
```

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

[](#configuration)

Permissions are generated from `config/picta-auth.php` under `picta-auth.permissions`.

```
return [
    'permissions' => [
        'models' => [
            'post' => \App\Models\Post::class,
            \App\Models\Comment::class,
        ],

        'actions' => [
            'view-any',
            'view',
            'create',
            'show',
            'update',
            'delete',
            'force-delete',
            'restore',
        ],
    ],
];
```

For API-only projects, you can also point notification links to frontend routes:

```
return [
    'frontend_urls' => [
        'reset_password' => env('AUTH_LIBRARY_FRONTEND_RESET_PASSWORD_URL'),
        'email_verification' => env('AUTH_LIBRARY_FRONTEND_EMAIL_VERIFICATION_URL'),
    ],
];
```

- `AUTH_LIBRARY_FRONTEND_RESET_PASSWORD_URL`: frontend page that receives `token` and `email` query params.
- `AUTH_LIBRARY_FRONTEND_EMAIL_VERIFICATION_URL`: frontend page that receives signed verification query params (`id`, `hash`, `expires`, `signature`).
- If `AUTH_LIBRARY_FRONTEND_RESET_PASSWORD_URL` is not set and no `password.reset` route exists, the package falls back to `APP_URL` + `picta-auth.routes.default_reset_password_path` (default: `/reset-password`).

Password reset validation rules are configurable via `picta-auth.password_rules`:

```
return [
    'password_rules' => ['required', 'string', 'confirmed', 'min:12'],
];
```

- `AUTH_LIBRARY_ISSUE_TOKEN_BY_DEFAULT` (optional): force login responses to always issue (`true`) or not issue (`false`) bearer tokens. By default, the package auto-detects: stateful frontend requests get cookie auth, non-stateful requests get bearer tokens.

If you publish the Bruno collection, create your local env file from the template:

```
cp bruno/auth/environments/Local.example.bru bruno/auth/environments/Local.bru
```

`bruno/auth/environments/Local.bru` is gitignored so personal values are not tracked.

Generated permission names follow:

```
{model}:{action}

```

Generate Permissions and Roles
------------------------------

[](#generate-permissions-and-roles)

```
php artisan auth:permissions:generate
```

This command keeps existing records and only creates missing permissions/roles.

User Model Trait
----------------

[](#user-model-trait)

Use the package trait on your User model to get:

- Sanctum API tokens
- Spatie roles/permissions support
- Default guard resolution from `picta-auth.guard`
- Convenience method: `$user->canAuthorize($model, $action)`

```
use Illuminate\Foundation\Auth\User as Authenticatable;
use PictaStudio\Auth\Concerns\HasAuthFeatures;

class User extends Authenticatable
{
    use HasAuthFeatures;
}
```

Global Helper
-------------

[](#global-helper)

```
auth_authorize(\App\Models\Post::class, 'view', $user);
auth_authorize(\App\Models\Post::class, 'update'); // defaults to auth()->guard()->user()
```

API Routes
----------

[](#api-routes)

Mounted under `/api/auth` by default:

- `POST /api/auth/register`
- `POST /api/auth/login`
- `GET /api/auth/me`
- `POST /api/auth/logout`
- `POST /api/auth/forgot-password`
- `POST /api/auth/reset-password`
- `POST /api/auth/email/verification-notification`
- `GET /api/auth/verify-email/{id}/{hash}`

Registration
------------

[](#registration)

`POST /api/auth/register` accepts:

- `name` (`string`, required)
- `email` (`email`, required, unique)
- `password` (`string`, required, defaults to `picta-auth.password_rules`)
- `password_confirmation` (required when using the default `confirmed` password rule)

Optional payload fields:

- `issue_token` (`boolean`): force token issuance on/off.
- `token_name` (`string`): token name when issuing bearer tokens.

Like login, registration defaults to cookie auth for stateful frontend requests and bearer token auth for non-stateful requests.

Login Modes
-----------

[](#login-modes)

`POST /api/auth/login` supports both Sanctum modes:

- First-party frontend (stateful request, `Origin`/`Referer` in `sanctum.stateful`): authenticates with cookies/session by default.
- Third-party clients (non-stateful request): returns a bearer token by default.

Optional payload fields:

- `issue_token` (`boolean`): force token issuance on/off.
- `token_name` (`string`): token name when issuing bearer tokens.

To use cookie-based SPA auth, make sure your frontend domain is in `config/sanctum.php` (`sanctum.stateful`) and keep `picta-auth.routes.stateful_middleware` enabled.

Frontend Integration (Cookie Auth)
----------------------------------

[](#frontend-integration-cookie-auth)

Use this flow when your first-party frontend authenticates with cookies (Sanctum stateful mode) instead of bearer tokens.

### 1. Backend setup

[](#1-backend-setup)

Set your frontend as a stateful domain and allow cross-site credentials.

Example `.env`:

```
APP_URL=http://api.test
SESSION_DRIVER=cookie
SESSION_DOMAIN=.test
SANCTUM_STATEFUL_DOMAINS=app.test,localhost:3000,127.0.0.1:3000
```

Example `config/cors.php`:

```
return [
    'paths' => ['api/*', 'api/auth/csrf-cookie'],
    'allowed_methods' => ['*'],
    'allowed_origins' => ['http://app.test', 'http://localhost:3000'],
    'allowed_headers' => ['*'],
    'supports_credentials' => true,
];
```

Notes:

- Keep `picta-auth.routes.stateful_middleware` enabled (default).
- The Sanctum CSRF route is exposed under the same prefix as your auth routes (`GET /api/auth/csrf-cookie` by default).
- The package will default `POST /api/auth/login` to cookie auth for these stateful frontend requests.
- For localhost-only development, you can leave `SESSION_DOMAIN` unset.
- For production subdomains, use a shared session domain (for example `.example.com`).

### 2. Frontend request flow

[](#2-frontend-request-flow)

1. Get CSRF cookie: `GET /api/auth/csrf-cookie` with credentials.
2. Login: `POST /api/auth/login` with email/password and credentials.
3. Read current user: `GET /api/auth/me` with credentials.
4. Logout: `POST /api/auth/logout` with credentials.

### 3. Frontend example (Axios)

[](#3-frontend-example-axios)

```
import axios from 'axios';

const api = axios.create({
  baseURL: 'http://api.test',
  withCredentials: true,
  withXSRFToken: true,
});

export async function login(email: string, password: string) {
  await api.get('/api/auth/csrf-cookie');

  await api.post('/api/auth/login', { email, password });

  const { data } = await api.get('/api/auth/me');
  return data.user;
}

export async function logout() {
  await api.post('/api/auth/logout');
}
```

### 4. Frontend example (Fetch)

[](#4-frontend-example-fetch)

```
const API_BASE = 'http://api.test';

export async function login(email: string, password: string) {
  await fetch(`${API_BASE}/api/auth/csrf-cookie`, {
    method: 'GET',
    credentials: 'include',
  });

  await fetch(`${API_BASE}/api/auth/login`, {
    method: 'POST',
    credentials: 'include',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, password }),
  });

  const meResponse = await fetch(`${API_BASE}/api/auth/me`, {
    method: 'GET',
    credentials: 'include',
  });

  const me = await meResponse.json();
  return me.user;
}
```

### 5. If login still returns tokens

[](#5-if-login-still-returns-tokens)

`POST /api/auth/login` can still issue bearer tokens when:

- The request is not detected as stateful (missing/mismatched `Origin` or `Referer`).
- You explicitly pass `issue_token: true`.
- You force token mode with `AUTH_LIBRARY_ISSUE_TOKEN_BY_DEFAULT=true`.

Morph Map
---------

[](#morph-map)

Inside your AppServiceProvider add this to ensure the relation morph map is registered:

```
use Illuminate\Support\ServiceProvider;
use PictaStudio\Auth\AuthServiceProvider;
use Illuminate\Database\Eloquent\Relations\Relation;
use App\Models\User;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Relation::morphMap([
            'user' => User::class,
        ]);
    }
}
```

Testing
-------

[](#testing)

```
composer test
```

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance89

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 93.5% 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 ~1 days

Total

8

Last Release

69d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/871c609368b67370ee8c9a0e1077d94ece3b358ee39703a5bdae118c0159f1b1?d=identicon)[pictastudio](/maintainers/pictastudio)

---

Top Contributors

[![Frameck](https://avatars.githubusercontent.com/u/77396783?v=4)](https://github.com/Frameck "Frameck (29 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (2 commits)")

---

Tags

spatielaravelauthsanctumrolespermissionsPicta Studio

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

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

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

###  Alternatives

[spatie/laravel-permission

Permission handling for Laravel 12 and up

12.9k89.8M1.0k](/packages/spatie-laravel-permission)[tymon/jwt-auth

JSON Web Token Authentication for Laravel and Lumen

11.5k49.1M350](/packages/tymon-jwt-auth)[bezhansalleh/filament-shield

Filament support for `spatie/laravel-permission`.

2.8k2.9M88](/packages/bezhansalleh-filament-shield)[php-open-source-saver/jwt-auth

JSON Web Token Authentication for Laravel and Lumen

8359.8M53](/packages/php-open-source-saver-jwt-auth)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k12.1M99](/packages/laravel-pulse)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)

PHPackages © 2026

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