weijukeji/laravel-iam

Laravel IAM (Identity and Access Management) package for managing users, roles, permissions and menus

Maintainers

Package info

github.com/WeiJuKeJi/laravel-iam

pkg:composer/weijukeji/laravel-iam

Transparency log

Statistics

Installs: 63

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.3.0 2026-07-13 16:32 UTC

This package is auto-updated.

Last update: 2026-07-13 16:36:34 UTC


README

Laravel Identity and Access Management (IAM) package - 用户、角色、权限、菜单、部门和登录日志管理。

功能

  • 用户管理 - CRUD、角色分配、部门/商户关联、软删除
  • 角色管理 - RBAC、权限绑定、菜单绑定、用户绑定
  • 权限管理 - 细粒度权限控制,分组管理(基于 Spatie Permission)
  • 菜单管理 - 嵌套树形结构、角色访问控制、公共菜单、外链/内嵌支持
  • 部门管理 - 树形组织架构,部门层级拖拽排序
  • 登录日志 - 登录记录查询,个人日志查看
  • 权限目录治理 - 从路由生成权限、中文显示名审计、接口面过滤
  • 权限强制 - 可配置的全局路由权限中间件和超级管理员 Gate bypass
  • 权限包与角色预置 - 配置驱动的权限包展开、角色权限和菜单同步
  • 菜单导出 - 导出菜单配置为 JSON

依赖

  • PHP >= 8.2
  • Laravel >= 11.0(支持 Laravel 12、13)
  • MySQL / PostgreSQL

安装

# 安装扩展包
composer require weijukeji/laravel-iam

# 运行安装命令
php artisan iam:install --seed

安装选项:

  • --seed - 运行数据填充(默认角色、权限、管理员账号)
  • --force - 覆盖已有配置文件
  • --no-migrate - 跳过迁移
  • --sync-permissions - 同步路由权限

手动安装

# 发布配置
php artisan vendor:publish --tag=iam-config

# 发布并运行迁移
php artisan vendor:publish --tag=iam-migrations
php artisan migrate

# 填充数据(可选)
php artisan db:seed --class="WeiJuKeJi\\LaravelIam\\Database\\Seeders\\IamDatabaseSeeder"

数据填充创建:

  • 默认权限(用户/角色/权限/菜单管理)
  • 默认角色(super-admin、Admin、Editor)
  • 管理员账号:admin@settlehub.local / Admin@123456
  • 默认菜单结构

配置

编辑 config/iam.php

return [
    // 数据表前缀
    'table_prefix' => 'iam_',

    // 认证守卫
    'guard' => 'sanctum',

    // observe 只观察;enforce 返回 403
    'enforcement' => [
        'mode' => env('IAM_PERMISSION_MODE', 'observe'),
        'surface' => 'admin',
        'denied_message' => '无权执行该操作',
    ],

    // 按认证中间件、路由名、URI 和控制器划分权限接口面
    'permission_sync' => [
        'surfaces' => [
            'admin' => [
                'required_middleware' => ['auth:sanctum'],
                'include_route_prefixes' => [],
                'exclude_route_prefixes' => [],
                'exclude_uri_prefixes' => [],
                'exclude_action_prefixes' => [],
            ],
        ],
    ],

    // 忽略的路由(不需要权限验证)
    'ignore_routes' => [
        'iam.auth.login',
        'iam.auth.logout',
        'iam.auth.me',
        'iam.auth.password',
        'iam.routes.index',
    ],

    // 动作映射
    'action_map' => [
        'index' => 'view',
        'show' => 'view',
        'store' => 'manage',
        'update' => 'manage',
        'destroy' => 'manage',
    ],

    // 权限包和角色预置可以指向项目自己的配置文件
    'permission_bundles' => [
        'config_key' => 'iam.permission_bundles.definitions',
        'definitions' => [],
    ],

    'super_admin' => [
        'enabled' => true,
        'roles' => ['super-admin'],
    ],
];

项目特定的中文词典、权限包、标准角色和菜单清单应保留在项目配置中。扩展包只提供解析、审计和同步机制,不内置业务权限 code。

权限治理命令

# 审计路由命名、权限解析、中文名和数据库覆盖
php artisan iam:audit-permissions --surface=admin

# 只同步权限目录和显示名,不修改任何角色授权
php artisan iam:sync-permissions --surface=admin --dry-run
php artisan iam:sync-permissions --surface=admin

# 同步项目配置定义的标准角色权限和菜单
php artisan iam:sync-role-presets --mode=additive --create-missing --dry-run
php artisan iam:sync-role-presets --mode=reconcile --show-bundles

additive 只补充缺失授权;reconcile 只在标准角色预置的受管范围内补充和撤销。权限目录同步与角色授权同步是两个独立动作,避免扫描局部路由时误改角色权限。

超级管理员默认通过 Gate::before 和配置的角色名实现虚拟全权限,不需要在 role_has_permissions 中物理绑定全部权限。RoleSeeder 默认会清理 super-admin 的物理权限关联;关闭 Gate bypass 时会自动恢复物理全权限。旧项目如果仍依赖直接调用 hasPermissionTo(),可临时配置:

'super_admin' => [
    'enabled' => true,
    'roles' => ['super-admin'],
    'materialize_permissions' => true,
],

推荐业务代码使用 $user->can($permission) 或 Gate/Policy,不要直接使用 hasPermissionTo() 作为接口授权判断,以确保超级管理员旁路语义一致。

materialize_permissions=false 时,角色更新接口会拒绝给配置的超级管理员角色绑定实体权限;受保护角色的角色名、守卫和删除操作也不可修改。

全局权限中间件

Laravel 11 及以上可在 bootstrap/app.php 的 API 中间件栈中加入:

use WeiJuKeJi\LaravelIam\Http\Middleware\AuthorizeRoutePermission;

$middleware->api(append: [AuthorizeRoutePermission::class]);

建议先使用 IAM_PERMISSION_MODE=observe 完成审计,再切换为 enforce。公开、游客、小程序或其他独立接口面应通过 permission_sync.surfaces 排除,业务对象的数据范围仍应由项目 Policy、Middleware 或 Service 校验。

从 1.2.x 升级到 1.3.0

  1. 更新依赖并发布最新配置。
  2. 将项目内通用的路由权限解析、显示名解析、审计命令和角色预置引擎替换为扩展包实现。
  3. 保留项目自己的中文词典、权限包和角色预置,并通过配置 key 或容器绑定接入。
  4. 先执行审计、权限目录 dry-run 和角色预置 dry-run,确认零意外撤销后再正式同步。

表前缀

table_prefix 影响以下表:

表名 说明
{prefix}permissions 权限表
{prefix}roles 角色表
{prefix}model_has_permissions 用户-权限关联
{prefix}model_has_roles 用户-角色关联
{prefix}role_has_permissions 角色-权限关联
{prefix}menus 菜单表
{prefix}menu_role 菜单-角色关联
{prefix}departments 部门表

建议在安装前配置前缀。已安装的项目修改前缀后需回滚并重新运行迁移。

缓存

建议使用支持标签的缓存驱动(Redis / Memcached)。file / database 驱动也能工作,会使用备用的缓存键追踪机制。

API 路由

默认路由前缀:/api/iam(可通过配置 route_prefix 修改)

认证

方法 路径 说明 限制
POST /auth/login 登录 5次/分钟
POST /auth/logout 登出 需认证
GET /auth/me 当前用户信息 需认证
PUT /auth/password 当前用户校验旧密码后修改本人密码,并撤销全部 Token 需认证,10次/分钟

菜单(权限:iam.menus.view / iam.menus.manage

方法 路径 说明
GET /routes 当前用户的路由菜单(带缓存)
GET /menus/tree 菜单树(管理端)
GET /menus 菜单列表
POST /menus 创建菜单
GET /menus/{id} 菜单详情
PUT /menus/{id} 更新菜单
DELETE /menus/{id} 删除菜单

用户(权限:iam.users.view / iam.users.manage

方法 路径 说明
GET /users 用户列表
POST /users 创建用户
GET /users/{id} 用户详情
PUT /users/{id} 更新用户
DELETE /users/{id} 删除用户

可通过配置 disabled_routes 禁用用户路由。

角色(权限:iam.roles.view / iam.roles.manage

方法 路径 说明
GET /roles 角色列表(支持 with_permissionswith_menuswith_users_count
POST /roles 创建角色
GET /roles/{id} 角色详情(支持 with_permissionswith_menus
PUT /roles/{id} 更新角色
DELETE /roles/{id} 删除角色(super-admin 禁止删除)

角色创建/更新支持字段:namedisplay_namegroupmetadatapermissions(权限 ID 数组)、menu_ids(菜单 ID 数组)。

权限(权限:iam.permissions.view / iam.permissions.manage

方法 路径 说明
GET /permissions 权限列表
GET /permissions/groups 权限分组树
POST /permissions 创建权限
GET /permissions/{id} 权限详情
PUT /permissions/{id} 更新权限
DELETE /permissions/{id} 删除权限

部门(权限:iam.departments.view / iam.departments.manage

方法 路径 说明
GET /departments 部门列表
GET /departments/tree 部门树
POST /departments 创建部门
GET /departments/{id} 部门详情
PUT /departments/{id} 更新部门
DELETE /departments/{id} 删除部门
POST /departments/{id}/move 移动部门

登录日志(权限:iam.login-logs.view

方法 路径 说明
GET /login-logs 登录日志列表
GET /login-logs/{id} 日志详情
GET /login-logs/my 当前用户的登录日志

Artisan 命令

# 安装
php artisan iam:install [--seed] [--force] [--no-migrate] [--sync-permissions]

# 同步权限(从路由自动生成)
php artisan iam:sync-permissions

# 导出菜单为 JSON
php artisan iam:menus:export [path]

# 重置菜单数据(清空并重新填充)
php artisan iam:menu:reseed [--force]

# 卸载
php artisan iam:uninstall [--force] [--keep-tables]

菜单访问控制

菜单可见性判断逻辑:

  1. 未启用 → 不可见
  2. super-admin 角色 → 全部可见
  3. 公共菜单is_public = true)→ 所有登录用户可见
  4. 关联了角色 → 用户必须拥有其中一个角色才可见
  5. 未关联任何角色且非公共 → 不可见

菜单与角色的绑定可从两个方向管理:

  • 角色编辑 → "绑定菜单" Tab(选择角色能看到的菜单)
  • 菜单编辑 → "绑定角色" Tab(选择哪些角色能看到此菜单)

菜单树按用户角色缓存,缓存 TTL 30 分钟,修改菜单或菜单-角色关联时自动刷新。

模型

User

继承 Illuminate\Foundation\Auth\User,使用 HasApiTokensHasRolesSoftDeletesFilterable

Role

扩展 Spatie Permission Role,额外字段:display_namegroupmetadata

关系:permissions(多对多)、menus(多对多,通过 menu_role)、users(多态多对多)。

Permission

扩展 Spatie Permission,额外字段:display_namegroupmetadata

Menu

字段:parent_idnamepathcomponentredirectsort_orderis_enabledis_publicmeta

关系:parentchildrenroles(多对多,通过 menu_role)。

支持外链(path// 开头)和内嵌网页(通过 iframe 组件)。

Department

树形组织架构,支持层级排序和拖拽移动。

代码示例

use WeiJuKeJi\LaravelIam\Models\User;
use WeiJuKeJi\LaravelIam\Services\MenuService;

$user = User::find(1);

// 权限检查
$user->hasPermissionTo('iam.users.view');
$user->hasRole('super-admin');

// 角色和权限分配
$user->assignRole('admin');
$user->givePermissionTo('iam.users.manage');

// 菜单服务
$menuService = app(MenuService::class);
$menus = $menuService->getMenuTreeForUser($user);
$menus = $menuService->getMenuTreeForUser($user, forceRefresh: true);
$menuService->flushCache();

卸载

# 1. 运行卸载命令
php artisan iam:uninstall

# 2. 移除包(必须加 --no-scripts)
composer remove weijukeji/laravel-iam --no-scripts

# 3. 重建包发现缓存
php artisan package:discover --ansi

一行命令:

php artisan iam:uninstall --force && composer remove weijukeji/laravel-iam --no-scripts && php artisan package:discover --ansi

前端集成

许可证

MIT License. 详见 LICENSE