Laravel-AAA, a customizable and modern package for Authentication + Authorization + Accounting for your laravel project
Authentication is one of web applications most critical and essential features. Web frameworks like Laravel provide many ways for users to authenticate.
You can implement Laravel authentication features quickly and securely. However, implementing these authentication features poorly can be risky, as malicious parties can exploit them.
But, we built a fully customizable package from ground-up to solve this!
Some Laravel-AAA's features in summary are:
- Secure!
- Easy to use.
- Fully customizable.
- Best practices applied.
- Latest versions of PHP and PHPUnit
- Most importantly, It's an Free Open Source Software (FOSS)!
Laravel-AAA is currently under heavy development. You can give your suggestions and feedback on our Discussions page.
First of all, you need a laravel installation, You can start a laravel project by running command:
composer create-project laravel/laravel my-awesome-laravel-app
Or if you already have Laravel, install laravel-aaa in your project by running:
composer require dnj/laravel-aaa
Then, publish configs using this command:
php artisan vendor:publish --tag=config
This will results:
INFO Publishing [config] assets.
Copying file [vendor/dnj/laravel-aaa/config/aaa.php] to [config/aaa.php] .................................................................... DONE
Copying file [vendor/dnj/laravel-user-logger/config/user-logger.php] to [config/user-logger.php] ............................................ DONE
As you see, there are a aaa.php config file that we use it later.
We deal with some concepts, like: Type
, TypeAbility
, TypeLocalizedDetails
, User
and Username
We define some Type
s in our app, consider a Type
is a user level that defines user has access to which fetures of your app.
The Type
has an id, a localized nameds that can be defined for any languages, maybe a parent, paybe some child, and some abilities.
Consider this as a permission for user, each ability is belong to a Type
.
Each user is has a Type and the Type define that this user has access to which fetures of your app.
Each user may have some usernames, username can be anything, like: email, cellphone, telegram id, ....
In this file, you can define the guest type, if user not exists in you app (or not logged in), the app will use this type for check permissions.
define the ID of the guest type in aaa.php
in guestType
property.
[
'guestType' => 2, // The id of guest type
];
Laravel-AAA provides support for polices You can define a polices by runnig command:
php artisan make:policy:aaa
Then, add your policies to AuthServiceProvider
:
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use App\Models\Post;
use App\Policies\PostPolicy;
class AuthServiceProvider extends ServiceProvider
{
/**
* The model to policy mappings for the application.
*
* @var array<class-string, class-string>
*/
protected $policies = [
Post::class => PostPolicy::class,
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
///
}
}
now, you can check permission like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* @return \Illuminate\Contracts\Support\Renderable
*/
public function getPost(Request $request)
{
$post = $request->get('post');
$response = Gate::inspect('view_post_permission', $post);
if ($response) {
// allow
} else {
// deny
}
return view('view_post', ['title' => $post->getTitle()]);
}
}
The ITypeManager
interface provides methods for creating, updating, and deleting types, Here's an example of how to create a new type:
use dnj\AAA\Contracts\ITypeManager;
use dnj\AAA\Contracts\IType;
class TypeController extends Controller
{
private $typeManager;
public function __construct(ITypeManager $typeManager)
{
$this->typeManager = $typeManager;
}
public function createType()
{
// the name of this type in diffrent languages
$localizedDetails = [
'en' => ['title' => 'Admin'],
'fr' => ['title' => 'Administratrice'],
'nl' => ['title' => 'beheerder'],
];
// abilities that we want to define for this type (user role)
$abilities = [
'add_post',
'edit_post',
'remove_post',
'publish_post',
]
// the subtype IDs, consider this type as parent of other types, that means this type will have permission to another types
$childIds = [
// id
];
// if you want to define any other data for this type, use this field
$meta = [
'notes' => 'Some notes about this type',
];
// save log for this action
$userActivityLog = true;
$type = $this->typeManager->create($localizedDetails, $abilities, $childIds, $meta, $userActivityLog);
}
public function updateType(IType $type, array $update)
{
$changes = [];
if (isset($update['localizedDetails'])) {
$changes['localizedDetails'] = $update['localizedDetails'];
}
if (isset($update['abilities'])) {
$changes['abilities'] = $update['abilities'];
}
if (isset($update['childIds'])) {
$changes['childIds'] = $update['childIds'];
}
if (isset($update['meta'])) {
$changes['meta'] = $update['meta'];
}
// save log for this action
$userActivityLog = true;
$type = $this->typeManager->create($type, $changes, $userActivityLog);
}
public function deleteType(IType $type)
{
// save log for this action
$userActivityLog = true;
$this->typeManager->delete($type, $userActivityLog);
}
}
The IUserManager
interface provides methods for creating, updating, and deleting users, Here's an example of how to create a new user:
use dnj\AAA\Contracts\IUserManager;
use dnj\AAA\Contracts\IUser;
use dnj\AAA\Contracts\ITypeManager;
use dnj\AAA\Contracts\IType;
class UserController extends Controller
{
private $userManager;
public function __construct(IUserManager $userManager)
{
$this->userManager = $userManager;
}
public function createUser()
{
// name of the user
$name = 'Hossein Hosni'
// username of the user
$username = 'hosni'; // or cellphone number, or any unique thing
// password of the user
$password = 'SomeStrongPassword@123';
// the id of the user, or the Type object
$type = 1;
// or create user as guest
$type = app(ITypeManager::class)->getGuestTypeID();
// if you want to define any other data for this user, use this field
$meta = [
'notes' => 'Some notes about this user',
];
// save log for this action
$userActivityLog = true;
$user = $this->userManager->create($name, $username, $type, $meta, $userActivityLog);
}
public function updateUser(IUser $user, array $update)
{
$changes = [];
if (isset($update['type'])) {
$changes['type'] = $update['type'];
}
if (isset($update['usernames'])) {
$changes['usernames'] = $update['usernames'];
}
// save log for this action
$userActivityLog = true;
$user = $this->userManager->create($user, $changes, $userActivityLog);
}
public function deleteUser(IUser $user)
{
// save log for this action
$userActivityLog = true;
$this->userManager->delete($user, $userActivityLog);
}
}
If you find any bugs, please report it by submitting an issue on our issue page with a detailed explanation. Giving some screenshots would also be very helpful.
You can also submit a feature request on our issue page or discussions and we will try to implement it as soon as possible. If you want to contribute to this project, please contribute to this project.
If you want to run this project in your local system, please follow this guide:
-
Fork this project
-
Clone the project to your local system using this command
$ git clone https://github.com/<your_github_username>/laravel-aaa.git
- Change directory to the root directory of this project
$ cd laravel-aaa
- Install all dependencies using
composer
$ composer install
- Run the project in development mode.