Looking to hire Laravel developers? Try LaraJobs

laravel-auth maintained by laraverse

Description
Laravel Sanctum authentication APIs with OTP verification, soft deletes, and JSON-driven RBAC.
Last update
2026/08/17 12:00 (dev-master)
License
Links
Downloads
8

Comments
comments powered by Disqus

laraverse/laravel-auth

Laravel Sanctum token APIs with 6-digit OTP email verification, OTP password reset, soft-deleted accounts, and JSON-driven RBAC (Spatie Permission).

Requirements

Those packages are required by this library and must be installed in the host app.

Install

composer require laraverse/laravel-auth
php artisan publish:sanctum-auth --force
php artisan migrate
php artisan db:seed --class=Database\\Seeders\\LaravelAuthSeeder
composer remove laraverse/laravel-auth

publish:sanctum-auth

Copies all Sanctum auth and RBAC source into the host app (namespaces become App\...) so the code lives in your project. After this, you can remove the package and the APIs still work.

php artisan publish:sanctum-auth --force
php artisan publish:sanctum-auth --force --migrate --seed

--force overwrites existing files (including app/Models/User.php). --migrate / --seed run after publishing.

Duplicate *personal_access_tokens* files in database/migrations are deleted; Sanctum creates that table from vendor.

php artisan publish:session-auth currently forwards to publish:sanctum-auth (session/web auth is not implemented).

This publishes:

Destination What
app/Http/Controllers/Auth/ Register, login, logout, email OTP, password, profile
app/Http/Requests/ Form requests
app/Http/Resources/UserResource.php API user resource
app/Http/Middleware/ RoleMiddleware, PermissionMiddleware
routes/auth.php Auth API routes (/api/auth/...)
app/Services/ AuthService, OtpService, PasswordService, ProfileService, RoleAndPermissionService
app/Notifications/ Email verification and password-reset OTP mails
app/Traits/ApiResponse.php JSON response helper
app/Concerns/HasUserPermissions.php Direct-permission checks
app/Enums/ UserRole, OtpPurpose
app/Models/ User, Role, Permission, Otp
app/Docs/roles_and_permissions.json RBAC JSON
app/Console/Commands/PermissionAssignCommand.php permission:assign
database/migrations/ Users (if missing), permissions/roles, soft deletes, otps
database/seeders/ PermissionSeeder, RoleSeeder, LaravelAuthSeeder
database/factories/UserFactory.php User factory
config/laravel-auth.php App User model; load_package_routes is false
app/Providers/AuthApiServiceProvider.php Loads routes/auth.php, middleware, Spatie models
postman/Laravel-Auth.postman_collection.json Postman collection for all auth APIs

It also registers AuthApiServiceProvider in bootstrap/providers.php. After this command, package routes are disabled so only the published files handle auth.

Then seed with:

php artisan db:seed --class=Database\\Seeders\\LaravelAuthSeeder

--force overwrites app/Models/User.php. Review that file after publishing.

Remove the package after publishing

Yes — the app can keep working without laraverse/laravel-auth once the code is published.

publish:sanctum-auth copies auth/RBAC into app/ and routes/auth.php, registers AuthApiServiceProvider, and adds laravel/sanctum and spatie/laravel-permission to the host composer.json (so Composer does not delete them when you remove this package).

Then:

composer remove laraverse/laravel-auth

Do not remove Sanctum or Spatie. Auth APIs, OTP, and RBAC then run only from your published files.

User model

If you do not run publish:sanctum-auth, add these traits to your User model:

use Illuminate\Auth\MustVerifyEmail;
use Illuminate\Contracts\Auth\MustVerifyEmail as MustVerifyEmailContract;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Sanctum\HasApiTokens;
use Laraverse\LaravelAuth\Concerns\HasUserPermissions;
use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable implements MustVerifyEmailContract
{
    use HasApiTokens, HasRoles, SoftDeletes, HasUserPermissions, MustVerifyEmail;
}

After publish:sanctum-auth, use the published App\Models\User (traits come from App\Concerns).

Auth guard

In config/auth.php, use a Sanctum guard (this package defaults laravel-auth.guard to sanctum):

'guards' => [
    'sanctum' => [
        'driver' => 'sanctum',
        'provider' => 'users',
    ],
],

Set LARAVERSE_AUTH_GUARD=sanctum in .env if you override the default.

Point the users provider at App\Models\User after publishing, or at the package model:

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => \App\Models\User::class,
    ],
],

Seed roles and permissions before registering users.

API

Prefix: api/auth (LARAVERSE_AUTH_PREFIX). Guest routes need no token. Protected routes use Authorization: Bearer {token}.

Routes live in routes/auth.php after publish:sanctum-auth.

Method Path Body Auth
POST /api/auth/register name, email, password, password_confirmation Guest
POST /api/auth/email/verify email, otp Guest
POST /api/auth/email/resend email Guest
POST /api/auth/login email, password Guest (verified users only)
POST /api/auth/logout Sanctum (revokes current token)
POST /api/auth/forgot-password email Guest
POST /api/auth/reset-password email, otp, password, password_confirmation Guest
PUT /api/auth/password current_password, password, password_confirmation Sanctum
GET /api/auth/profile Sanctum + view-profile
PUT /api/auth/profile name, email Sanctum + update-profile
DELETE /api/auth/account Sanctum (soft delete)

Register creates an unverified user, assigns the default user role, and emails an OTP. No token is issued until login after verification.

Login returns a Sanctum token and user resource. Unverified users get 403. Soft-deleted users cannot log in.

Changing profile email clears email_verified_at and sends a new verification OTP.

OTP

  • 6-digit numeric codes, emailed (never returned in JSON)
  • Stored hashed (Hash::make)
  • Default TTL 10 minutes (laravel-auth.otp.ttl_minutes)
  • Purposes: email verification (register) and password reset (forgot-password)
  • Resend invalidates unused codes for the same email + purpose
  • Failed verifies increment attempts (max 5)

Soft delete

DELETE /api/auth/account sets deleted_at, revokes all tokens, and prefixes the email with deleted_{id}_ so the original address can register again. Soft-deleted users cannot log in.

RBAC

Published JSON: app/Docs/roles_and_permissions.json (package source: resources/rbac/roles_and_permissions.json). Override path with laravel-auth.rbac_json_path.

Role Permissions
admin dashboard, view-profile, update-profile
user dashboard, view-profile, update-profile

Re-sync a role’s users after JSON changes:

php artisan permission:assign admin

Example responses

Success (ApiResponse::successResponse):

{
  "success": true,
  "message": "Logged in successfully",
  "data": {
    "token": "1|plainTextToken",
    "token_type": "Bearer",
    "user": {
      "id": 1,
      "name": "Jane Doe",
      "email": "jane@example.com"
    }
  }
}

Error (ApiResponse::errorResponse):

{
  "success": false,
  "message": "Given data is invalid",
  "errors": {
    "email": ["The email field is required."]
  }
}

Postman

After publish:sanctum-auth, import:

postman/Laravel-Auth.postman_collection.json

In Postman: Import → File and select that JSON.

Collection variables: base_url (default http://localhost:8000), email, password, otp, token. Login saves token automatically. Put OTP codes from storage/logs/laravel.log when MAIL_MAILER=log.