A standalone authentication package using Laravel Passport and Spatie Permission.
elgibor-solution/laravel-authentication is a Laravel package for a standalone authentication package using laravel passport and spatie permission..
It currently has 0 GitHub stars and 74 downloads on Packagist (latest version v1.2.0).
Install it with composer require elgibor-solution/laravel-authentication.
Discover more Laravel packages by elgibor-solution
or browse all Laravel packages to compare alternatives.
Last updated
Enterprise-grade, multi-tenant ready authentication and authorization engine for Laravel.
Build secure, scalable API authentication processes with built-in role & permission management, seamless stancl/tenancy integration, and automated setup — right out of the box.
| Category | Capability |
| :--- | :--- |
| Authentication Engine | Robust API token generation and validation powered by Laravel Passport. |
| Role & Permission | Built-in custom roles and permissions management (No need for Spatie). |
| Multi-Tenant | Shared-database or Database-per-tenant architectures natively supported via stancl/tenancy. |
| Automated Setup | 1-click installation via Artisan command to scaffold migrations, keys, and configs. |
| Standardized API | Consistent HTTP status codes (200, 422, 401) wrapped in standard JSON formats. |
| Extensible Relations | Eager-load dynamic relationships (e.g., profiles, agency data) automatically upon fetching /me. |
Run the following command in your main project terminal to download the package:
composer require elgibor-solution/laravel-authentication
Instead of configuring migrations and settings manually, run this automation command:
php artisan elgibor-auth:install
The wizard will automatically:
roles, permissions tables, etc.).stancl/tenancy. (If yes, it smartly moves migrations to the tenant/ directory and generates keys securely).php artisan passport:install or passport:keys).config/auth.php file by injecting the api guard.app/Models/User.php model.To customize the flexibility of this package, publish the configuration file to your application's root directory:
php artisan vendor:publish --tag=authentication-config
This publishes config/authentication.php where you can customize all settings.
The full configuration lives in config/authentication.php. Below are the most important sections:
// config/authentication.php
return [
// Base URL prefix for all authentication endpoints
'prefix' => 'api/auth',
// Core middleware required for the package to function
'middleware' => ['api', 'tenant'],
// Require extra fields during login (e.g., 'tenant_id' for single-db tenancy)
'login_extra_fields' => [],
// Automatically eager-load relationships when calling the `/me` endpoint
'load_relations' => ['profile', 'agency'],
// Toggle tenant data in the `/me` response
'two_step_login' => [
'enabled' => false,
'include_tenant_in_response' => true,
],
];
This package is designed to work seamlessly with stancl/tenancy for database-per-tenant isolation.
If you run php artisan elgibor-auth:install and select "Yes" for stancl/tenancy:
oauth_* migrations into database/migrations/tenant/ (roles and permissions migrations remain in the central database).In Laravel 11, you must ensure the tenant middleware is registered in your application. Open your project's bootstrap/app.php file and add the alias:
->withMiddleware(function (Middleware $middleware): void {
$middleware->alias([
'tenant' => \Stancl\Tenancy\Middleware\InitializeTenancyByDomain::class,
]);
})
Ensure the tenant middleware is injected into the package's configuration:
// config/authentication.php
'middleware' => ['api', 'tenant'],
Since the database is isolated, you must create a Personal Access Client inside each newly created tenant:
php artisan tenants:run passport:client --personal
Ensure the User Model in your project uses the traits provided by the package (this is done automatically if you used the install command):
use ElgiborSolution\Authentication\Traits\HasCustomRole;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable {
use HasApiTokens, HasCustomRole;
}
Submit credentials to retrieve your access token:
curl -X POST http://your-app/api/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "password123"
}'
Retrieve the authenticated user's profile, including their flattened permissions array and, when enabled, the tenant object:
curl http://your-app/api/auth/me \
-H "Authorization: Bearer <your-access-token>"
Create a new role with assigned permissions:
curl -X POST http://your-app/api/auth/roles \
-H "Authorization: Bearer <your-access-token>" \
-H "Content-Type: application/json" \
-d '{
"role_name": "Manager",
"role_description": "Store manager",
"permissions": [1, 2, 5]
}'
If you need to validate custom logic (e.g., checking if a user belongs to a specific tenant_id, checking subscription status, or verifying account activation) after the email/password succeeds but before the token is generated, you can listen to the UserAuthenticated event.
Generate a listener in your application (not inside the package):
php artisan make:listener CheckCustomLoginRules
Open your new listener and use the UserAuthenticated event. You have full access to the $user and the $request payload.
namespace App\Listeners;
use ElgiborSolution\Authentication\Events\UserAuthenticated;
class CheckCustomLoginRules
{
public function handle(UserAuthenticated $event)
{
$user = $event->user;
$request = $event->request;
// Example 1: Read a payload from the request
$tenantId = $request->input('tenant_id');
if ($tenantId && !$user->tenants()->where('tenant_id', $tenantId)->exists()) {
// Return an array for structured validation errors. This will cancel the login.
return ['tenant_id' => ['You do not have access to this workspace.']];
}
// Example 2: Check user status
if (!$user->is_active) {
// Return a string for a generic error message. This will cancel the login.
return "Your account is disabled.";
}
// Example 3: Return boolean false
// return false; // Returns a default "Login interrupted by custom checks." error.
// If all checks pass, return null/void to let the package issue the token.
}
}
Register the listener in your EventServiceProvider:
use ElgiborSolution\Authentication\Events\UserAuthenticated;
use App\Listeners\CheckCustomLoginRules;
protected $listen = [
UserAuthenticated::class => [
CheckCustomLoginRules::class,
],
];
The login route is public and has '/auth' stripped from the prefix.
| Method | Endpoint | Description | Request Body |
| :--- | :--- | :--- | :--- |
| POST | /api/login | Authenticate user and issue token | email, password, + login_extra_fields |
These routes require the auth:api middleware and are prefixed with /api/auth.
| Method | Endpoint | Description | Request Body |
| :--- | :--- | :--- | :--- |
| GET | /api/auth/me | Get current user profile (with roles/tenant) | — (Requires Authorization Header) |
| POST | /api/auth/logout | Revoke the current access token | — (Requires Authorization Header) |
All routes require the auth:api middleware.
| Method | Endpoint | Description |
| :--- | :--- | :--- |
| GET | /roles | List all roles (paginated and cached) |
| POST | /roles | Create a new role with specific permissions |
| GET | /roles/{id} | Show specific role details |
| PUT | /roles/{id} | Update an existing role |
| DELETE | /roles/{id} | Delete a role (if not protected) |
| GET | /permissions | List all available permissions |
| PATCH | /permissions/{id}/toggle-status | Toggle permission status (Active 1 / Inactive 9) |