PHPackages                             cuongnx/laravel-mongodb-permission - 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. cuongnx/laravel-mongodb-permission

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

cuongnx/laravel-mongodb-permission
==================================

A flexible and multi-guard Role &amp; Permission system for Laravel 11+ and 12+, using MongoDB and inspired by Spatie.

v2.3.1(2w ago)4363MITPHPPHP ^8.1

Since Jul 12Pushed 2w agoCompare

[ Source](https://github.com/xuancuong220691/laravel-mongodb-permission)[ Packagist](https://packagist.org/packages/cuongnx/laravel-mongodb-permission)[ RSS](/packages/cuongnx-laravel-mongodb-permission/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (6)Versions (10)Used By (0)

laravel-mongodb-permission
==========================

[](#laravel-mongodb-permission)

[![Packagist](https://camo.githubusercontent.com/c176e7b3a7af84fd401e5dfbddd72e48cb8f1f4853229d0857e8bc6d70c5d681/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f63756f6e676e782f6c61726176656c2d6d6f6e676f64622d7065726d697373696f6e)](https://packagist.org/packages/cuongnx/laravel-mongodb-permission)[![Laravel](https://camo.githubusercontent.com/0b54a14e9c8ecbfbc8c6af588e474039bed98bdd341110cacf2833525faa87ef/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d313125323025374325323031322d6f72616e6765)](https://laravel.com)[![MongoDB](https://camo.githubusercontent.com/61aeb73efaf7bb47d9bfdc04371e0e975742ab51c4643128d60ae3c3e09d1c7e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d6f6e676f44422d352e342b2d677265656e)](https://www.mongodb.com)[![License](https://camo.githubusercontent.com/b8cadaa967891081f8f165695470689986c028821dd8a040132f6e661795dc0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c7565)](LICENSE)

Role &amp; Permission system cho Laravel + MongoDB. Hỗ trợ đa guard, không cần SQL, lưu trữ hoàn toàn trên MongoDB. Tích hợp sẵn với **Filament v3/v4/v5** qua `MongoShieldPlugin`.

---

Mục lục
-------

[](#mục-lục)

- [Yêu cầu](#y%C3%AAu-c%E1%BA%A7u)
- [Cài đặt](#c%C3%A0i-%C4%91%E1%BA%B7t)
- [Cấu trúc dữ liệu MongoDB](#c%E1%BA%A5u-tr%C3%BAc-d%E1%BB%AF-li%E1%BB%87u-mongodb)
- [Setup Model](#setup-model)
- [HasRoles API](#hasroles-api)
- [Middleware](#middleware)
- [Blade Directives](#blade-directives)
- [Artisan — mp:manage](#artisan--mpmanage)
- [PermissionService (DI)](#permissionservice-dependency-injection)
- [Cascade Cleanup](#cascade-cleanup)
- [Shield — Filament Integration](#shield--filament-integration)
    - [1. Đăng ký Plugin](#1-%C4%91%C4%83ng-k%C3%BD-plugin)
    - [2. Sinh Permissions tự động](#2-sinh-permissions-t%E1%BB%B1-%C4%91%E1%BB%99ng)
    - [3. Form UI cho RoleResource](#3-form-ui-cho-roleresource)
    - [4. Phân quyền cho Resources — Policy + Gate](#4-ph%C3%A2n-quy%E1%BB%81n-cho-resources--policy--gatebefore)
    - [5. Phân quyền cho Pages — HasPageShield](#5-ph%C3%A2n-quy%E1%BB%81n-cho-pages--haspageshield)
    - [6. Phân quyền cho Widgets — HasWidgetShield](#6-ph%C3%A2n-quy%E1%BB%81n-cho-widgets--haswidgetshield)
    - [7. Permission naming convention](#7-permission-naming-convention)
- [License](#license)

---

Yêu cầu
-------

[](#yêu-cầu)

Phiên bảnPHP`^8.1`Laravel`^11.0 || ^12.0`mongodb/laravel-mongodb`^5.4`filament/filament *(optional)*`^3.0 || ^4.0 || ^5.0`---

Cài đặt
-------

[](#cài-đặt)

```
composer require cuongnx/laravel-mongodb-permission
```

Service provider được tự động đăng ký qua Laravel package discovery.

Publish config:

```
php artisan vendor:publish --tag=mongo-permission
```

---

Cấu hình
--------

[](#cấu-hình)

`config/mongo-permission.php` — khai báo các Model sử dụng `HasRoles` để thư viện tự động cascade cleanup khi xóa role/permission:

```
return [
    'models' => [
        App\Models\Admin::class,
        App\Models\User::class,
    ],
];
```

---

Cấu trúc dữ liệu MongoDB
------------------------

[](#cấu-trúc-dữ-liệu-mongodb)

```
Collection: roles
{ _id, name: "moderator", guard_name: "admin", permissions: ["users.view", "users.update"] }

Collection: permissions
{ _id, name: "users.view", guard_name: "admin" }

Collection: admins  (hoặc bất kỳ model nào dùng HasRoles)
{ ..., role_ids: [""], permission_ids: [] }

```

- `role.permissions` — lưu tên permission dạng string array (không dùng ObjectId)
- `admin.role_ids` — ObjectId string của các roles được gán
- `admin.permission_ids` — ObjectId string của các direct permissions (hiếm dùng)

---

Setup Model
-----------

[](#setup-model)

Gắn trait `HasRoles` vào model và khai báo `$guard_name`:

```
use CuongNX\LaravelMongoPermission\Traits\HasRoles;

class Admin extends Authenticatable
{
    use HasRoles;

    protected $guard_name = 'admin';

    public function isSuperAdmin(): bool
    {
        return $this->hasRole('super-admin');
    }
}
```

> `$guard_name` quyết định thư viện tìm role/permission theo guard nào. Nếu bỏ qua, mặc định dùng `config('auth.defaults.guard')`.

---

HasRoles API
------------

[](#hasroles-api)

### Roles

[](#roles)

```
$admin->assignRole('moderator');                   // gán (bỏ qua nếu đã có)
$admin->removeRole('moderator');                   // gỡ
$admin->revokeRole('moderator');                   // alias của removeRole()
$admin->syncRoles(['moderator', 'editor']);         // thay toàn bộ

$admin->hasRole('moderator');                      // bool — cache per-request
$admin->hasAnyRole(['admin', 'editor']);            // bool — ít nhất 1
$admin->hasAllRoles(['admin', 'editor']);           // bool — phải có đủ

$admin->getRoleNames();                            // Collection
```

### Permissions

[](#permissions)

```
$admin->givePermissionTo('users.create');          // direct permission
$admin->revokePermissionTo('users.create');
$admin->syncPermissions(['users.view', 'users.update']);

$admin->hasPermissionTo('users.view');             // bool — direct OR via role, cache per-request
$admin->hasAnyPermission(['users.view', 'users.delete']);
$admin->hasAllPermissions(['users.view', 'users.update']);

$admin->getAllPermissions();                        // string[] — direct + via roles, unique
```

> **Cache:** Kết quả `hasRole`/`hasPermissionTo` được cache theo key `::` trong suốt vòng đời request. Tự xóa khi gọi bất kỳ method mutation nào.

---

Middleware
----------

[](#middleware)

```
// Kiểm tra role — OR bằng dấu |
Route::middleware('role:super-admin')->...
Route::middleware('role:super-admin|moderator')->...

// Kiểm tra permission
Route::middleware('permission:users.view')->...
Route::middleware('permission:users.view|users.create')->...

// Chỉ định guard tường minh (tham số thứ 2)
Route::middleware('role:super-admin,admin')->...
Route::middleware('permission:users.view,admin')->...
```

---

Blade Directives
----------------

[](#blade-directives)

```
@role('super-admin')
    Chỉ super-admin thấy
@endrole

@role('super-admin', 'admin')       {{-- với guard cụ thể --}}
    ...
@endrole

@permission('users.view')
    ...
@endpermission

@permission('users.view', 'admin')
    ...
@endpermission

@anyrole('super-admin', 'moderator')            {{-- default guard --}}
    ...
@endanyrole

@anyrolefor('admin', 'super-admin', 'moderator') {{-- guard tường minh --}}
    ...
@endanyrolefor

@anypermission('users.view', 'users.create')
    ...
@endanypermission

@anypermissionfor('admin', 'users.view', 'users.create')
    ...
@endanypermissionfor
```

---

Artisan — mp:manage
-------------------

[](#artisan--mpmanage)

```
php artisan mp:manage [options] [--guard=web]
```

### Roles

[](#roles-1)

```
php artisan mp:manage --create-role=super-admin,moderator --guard=admin
php artisan mp:manage --delete-role=moderator --guard=admin
php artisan mp:manage --list-roles --guard=admin
php artisan mp:manage --show-role=moderator --guard=admin
```

### Permissions

[](#permissions-1)

```
php artisan mp:manage --create-permission=users.view,users.create,users.update,users.delete --guard=admin
php artisan mp:manage --delete-permission=users.delete --guard=admin
php artisan mp:manage --list-permissions --guard=admin
```

### Gán / Gỡ

[](#gán--gỡ)

```
# cú pháp: role:perm1,perm2
php artisan mp:manage --assign-permission=moderator:users.view,users.update --guard=admin
php artisan mp:manage --revoke-permission=moderator:users.update --guard=admin
```

### Export / Import

[](#export--import)

```
php artisan mp:manage --export=storage/permissions.json --guard=admin
php artisan mp:manage --import=storage/permissions.json --guard=admin
```

Format file JSON:

```
{
    "permissions": [
        { "name": "users.view", "guard_name": "admin" }
    ],
    "roles": [
        { "name": "moderator", "guard_name": "admin", "permissions": ["users.view", "users.update"] }
    ]
}
```

### Sync permissions từ file

[](#sync-permissions-từ-file)

```
# cú pháp: role:path/to/file.json
php artisan mp:manage --sync-role-permissions=moderator:storage/moderator.json --guard=admin
```

### Reset

[](#reset)

```
php artisan mp:manage --reset --guard=admin    # xóa guard này (fire events → cascade)
php artisan mp:manage --reset-all               # truncate toàn bộ mọi guard (không fire events)
```

---

PermissionService (Dependency Injection)
----------------------------------------

[](#permissionservice-dependency-injection)

```
use CuongNX\LaravelMongoPermission\Services\Contracts\PermissionServiceInterface;

class RoleController extends Controller
{
    public function __construct(private PermissionServiceInterface $permissions) {}

    public function store()
    {
        $this->permissions->createRoles('moderator,editor', 'admin');
        $this->permissions->assignPermissions('moderator', 'users.view,users.update', 'admin');
    }
}
```

MethodMô tả`createRoles(string, string)`Tạo roles, bỏ qua nếu đã tồn tại`deleteRoles(string, string)`Xóa roles (cascade cleanup)`createPermissions(string, string)`Tạo permissions`deletePermissions(string, string)`Xóa permissions (cascade cleanup)`assignPermissions(string $role, string $perms, string $guard)`Gán permissions vào role`revokePermissions(string $role, string $perms, string $guard)`Gỡ bớt permissions khỏi role`listRoles(string)`Danh sách roles`listPermissions(string)`Danh sách permissions`showRole(string, string)`Chi tiết 1 role`exportToFile(string $path, ?string $guard)`Xuất JSON`importFromFile(string $path, string $guard)`Nhập JSON`syncRolePermissions(string $role, string $jsonPath, string $guard)`Sync từ file`reset(?string $guard)`Xóa guard (events) hoặc truncate toàn bộKết quả array có keys: `created`, `skipped`, `deleted`, `assigned`, `revoked`, `synced`, `failed`.

---

Cascade Cleanup
---------------

[](#cascade-cleanup)

Khi **xóa Role**: tự động xóa `role_ids` tương ứng khỏi tất cả user documents trong `config('mongo-permission.models')`.

Khi **xóa Permission**: tự động xóa permission name khỏi `permissions[]` của tất cả Role documents, và xóa `permission_ids` khỏi user documents.

> `reset($guard)` xóa từng document → fire model events → cascade cleanup chạy bình thường.
> `reset()` không tham số dùng `truncate()` — nhanh hơn nhưng **không** fire events và xóa **toàn bộ mọi guard**.

---

Shield — Filament Integration
-----------------------------

[](#shield--filament-integration)

> **Yêu cầu:** `filament/filament ^3.0|^4.0|^5.0`

Shield tích hợp thư viện với Filament admin panel, tương tự `bezhansalleh/filament-shield` nhưng dành cho MongoDB:

- **Auto-generate permissions** từ Resources, Pages, Widgets đăng ký trong panel
- **Form UI dạng Tabs** cho RoleResource (Tài nguyên / Trang / Widget)
- **`HasPageShield` / `HasWidgetShield` traits** — Page và Widget tự kiểm tra quyền qua Gate
- **`Gate::before()` cho super-admin** — bypass toàn bộ checks, không cần gán permission
- **Policy generator** — tự sinh Laravel Policy files từ stub
- **Artisan `mp:shield:generate`** — đồng bộ permissions vào MongoDB

### 1. Đăng ký Plugin

[](#1-đăng-ký-plugin)

```
// app/Providers/Filament/AdminPanelProvider.php
use CuongNX\LaravelMongoPermission\Filament\MongoShieldPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            MongoShieldPlugin::make()
                ->panelId('admin')
                ->superAdminRole('super-admin')
                ->withPagePermissions()
                ->withWidgetPermissions(),
        ]);
}
```

#### Tùy chọn plugin

[](#tùy-chọn-plugin)

MethodMặc địnhMô tả`->panelId(string)``'admin'`Filament panel ID để quét Resources`->resourceActions(array)``['view','create','update','delete']`Actions sinh per-resource`->separator(string)``'.'`Ký tự ngăn cách (e.g. `users.view`)`->superAdminRole(string)``'super-admin'`Role bypass tất cả permission checks qua `Gate::before()``->withPagePermissions()``false`Sinh thêm permissions cho standalone Pages`->withWidgetPermissions()``false`Sinh thêm permissions cho Widgets### 2. Sinh Permissions tự động

[](#2-sinh-permissions-tự-động)

```
# Resources + Pages + Widgets, xóa stale, sinh Policy files
php artisan mp:shield:generate \
    --panel=admin --guard=admin \
    --pages --widgets --policies --clean

# Xem trước, không ghi
php artisan mp:shield:generate --dry-run

# Chỉ Resources
php artisan mp:shield:generate --panel=admin --guard=admin
```

Ví dụ output:

```
▸ Người dùng
    users.view → Xem
    users.create → Tạo
    users.update → Sửa
    users.delete → Xóa
▸ Pages
    page.lvcoin-adjustment → Điều chỉnh LVcoin
▸ Widgets
    widget.stats-overview → Stats Overview

Tổng: 42 permissions từ 10 resources + 1 pages + 1 widgets.
✅ Permissions: 42 tạo mới · 0 đã tồn tại | Policies: 10 tạo mới · 0 bỏ qua.

```

### 3. Form UI cho RoleResource

[](#3-form-ui-cho-roleresource)

Dùng trait `HasShieldFormComponents` trong `RoleResource`:

```
use CuongNX\LaravelMongoPermission\Filament\Traits\HasShieldFormComponents;

class RoleResource extends Resource
{
    use HasShieldFormComponents;

    public static function form(Schema $schema): Schema
    {
        return $schema->components([
            TextInput::make('name')->label('Tên vai trò')->required(),
            Select::make('guard_name')
                ->options(['admin' => 'Admin Panel'])
                ->default('admin'),
            static::getShieldFormComponents(),
        ]);
    }
}
```

Form hiển thị dạng **Tabs**:

- **Tài nguyên** — collapsible Section per resource, checkboxes Xem/Tạo/Sửa/Xóa, badge = tổng permissions
- **Trang** — CheckboxList phẳng tất cả Pages, badge = số Pages
- **Widget** — CheckboxList phẳng tất cả Widgets, badge = số Widgets
- Toggle **"Chọn tất cả"** ở trên đầu — check/uncheck toàn bộ 3 tab cùng lúc

**Cơ chế hoạt động:**

- Mỗi group/tab dùng `CheckboxList` synthetic (`__shield_*`) với `dehydrated(false)`
- `afterStateHydrated` — filter `role.permissions` cho từng group khi load
- `afterStateUpdated` — merge tất cả groups vào `Hidden('permissions')`
- Filament lưu `Hidden('permissions')` vào `role.permissions` — không cần override gì thêm

### 4. Phân quyền cho Resources — Policy + Gate::before

[](#4-phân-quyền-cho-resources--policy--gatebefore)

Cách khuyến nghị: dùng **Policy + `Gate::before()`** thay vì `canAccess()` thủ công.

**Bước 1:** Chạy `--policies` để sinh Policy files:

```
php artisan mp:shield:generate --policies
```

Policy được sinh tự động vào `app/Policies/UserPolicy.php`:

```
class UserPolicy
{
    public function viewAny(AuthUser $user): bool {
        return method_exists($user, 'hasPermissionTo') && $user->hasPermissionTo('users.view');
    }
    public function view(AuthUser $user, User $model): bool { ... }
    public function create(AuthUser $user): bool { ... }
    public function update(AuthUser $user, User $model): bool { ... }
    public function delete(AuthUser $user, User $model): bool { ... }
}
```

**Bước 2:** Xóa `canAccess()` khỏi Resource — Filament tự gọi `Gate::allows('viewAny', $model)` → Policy:

```
// Không cần canAccess() — Policy xử lý tự động
class UserResource extends Resource
{
    protected static ?string $model = User::class;
    // ...
}
```

**Super-admin bypass:** `MongoShieldPlugin` đăng ký `Gate::before()` khi boot — super-admin tự động pass mọi check mà không cần gán permission.

### 5. Phân quyền cho Pages — `HasPageShield`

[](#5-phân-quyền-cho-pages--haspageshield)

Thay vì viết `canAccess()` thủ công, dùng trait:

```
use CuongNX\LaravelMongoPermission\Filament\Traits\HasPageShield;

class LvcoinAdjustment extends Page
{
    use HasPageShield;
    // canAccess() tự động: Gate::allows('page.lvcoin-adjustment')
    // Super-admin bypass qua Gate::before()
}
```

Trait tự động derive permission name từ class name: `LvcoinAdjustment` → `page.lvcoin-adjustment`.

### 6. Phân quyền cho Widgets — `HasWidgetShield`

[](#6-phân-quyền-cho-widgets--haswidgetshield)

```
use CuongNX\LaravelMongoPermission\Filament\Traits\HasWidgetShield;

class StatsOverviewWidget extends Widget
{
    use HasWidgetShield;
    // canView() tự động: Gate::allows('widget.stats-overview-widget')
}
```

### 7. Permission naming convention

[](#7-permission-naming-convention)

LoạiClassPermissionResource`App\Models\User``users.view`, `users.create`, `users.update`, `users.delete`Resource`App\Models\OAuthClient``oauth-clients.view`, ...Page`LvcoinAdjustment``page.lvcoin-adjustment`Widget`StatsOverviewWidget``widget.stats-overview-widget`- Resource slug: `Str::plural(Str::kebab(class_basename($modelClass)))`
- Page/Widget slug: `Str::kebab(class_basename($class))`

---

License
-------

[](#license)

MIT © [Cuong Nguyen](mailto:xuancuong220691@gmail.com)

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance96

Actively maintained with recent releases

Popularity19

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

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 ~48 days

Recently: every ~24 days

Total

9

Last Release

18d ago

Major Versions

v1.1.1 → v2.0.02025-07-12

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/12405391?v=4)[Xuân Cương](/maintainers/xuancuong220691)[@xuancuong220691](https://github.com/xuancuong220691)

---

Top Contributors

[![xuancuong220691](https://avatars.githubusercontent.com/u/12405391?v=4)](https://github.com/xuancuong220691 "xuancuong220691 (12 commits)")

### Embed Badge

![Health badge](/badges/cuongnx-laravel-mongodb-permission/health.svg)

```
[![Health](https://phpackages.com/badges/cuongnx-laravel-mongodb-permission/health.svg)](https://phpackages.com/packages/cuongnx-laravel-mongodb-permission)
```

###  Alternatives

[statamic-rad-pack/runway

Eloquently manage your database models in Statamic.

137236.2k8](/packages/statamic-rad-pack-runway)[duncanmcclean/statamic-cargo

Comprehensive e-commerce addon for Statamic. Build bespoke e-commerce sites without the complexity.

3622.8k](/packages/duncanmcclean-statamic-cargo)

PHPackages © 2026

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