zoukankan      html  css  js  c++  java
  • Entrust是一种为Laravel5添加基于角色的权限的简洁而灵活的方法。

    安装

    首先要在composer.json中添加:

    "zizaco/entrust": "5.2.x-dev"

    然后运行composer install 或者 composer update

    在 config.php的provider数组中添加:

    ZizacoEntrustEntrustServiceProvider::class,

    在config.php的alias数组中添加:

    'Entrust'=>ZizacoEntrustEntrustFacade::class,

    如果你要使用中间件(要求5.1或更高版本),你需要在appHttpkernel.php的routeMiddleware数组中添加:

    'role'=>izacoEntrustMiddlewareEntrustRole::class,
    'permission'=>izacoEntrustMiddlewareEntrustPermission::class,
    'ability'=>izacoEntrustMiddlewareEntrustAbility::class, 配置

    在config/auth.php设置属性值。这是值将被用于给entrust指定正确的用户表和模型。

    你也可以发布这个包的配置以便进一步的配置表明和命名空间。

    只要使�php artisan vendor:publish , entrsust.php就会被创建到app/config文件夹中。

    用户关联到角色

    现在生成enrust迁移:

    php artisan entrust:migration

    这将生成<timestamp>_entrust_setup_tables.ph迁移。你这时可以使用迁移命令运行它了:

    php artisan migrate

    迁移结束后,会创建4张新表:

    1. roles - 存储角色记录

    2. permissions - 存储权限记录

    3. role_user - 存储角色与用户之间多对多关联

    4. peimissionrole - 存储角色和权限之间多对多关联

    模型 Role

    使用下面的示例创建app/models/Role.php作为角色模型:

    <?php
    namespace App;
    use ZizacoEntrustEntrustRole;
    class Role extends EntrustRole{
    }

    角色模型有3个主要属性:

    1. name - 唯一的角色名称,用于在应用信息层查找角色信息。例如:“admin”,“owner”,“employee”。

    2. display_name - 人类可读的角色名称。不一定是唯一和可选的。“User Administrator”,“Project Owner”,“Widget Co.Employee”。

    3. description - 关于角色作用更详细的解释。 同样是可选的。

    display_name 和 description同样可选的。在数据库中他们可以为空。

    权限

    使用下面的示例创建app/models/Permission.php作为权限模型:

    <?php
    namespace App; 
    use ZizacoEntrustEntrustPermission;
    class Permission extends EntrustPermission{
    }

    权限模型拥有和角色模型同样的三个主要属性:

    1. name - 唯一的权限名称,用于在应用层查找权限信息。例如"create-post",“edit-user”,“post-payment”,“mailing-list-subscribe”。

    2. display_name - 人类可读的权限名称。不一定是唯一和可选的。例如:“Create Post",“Post Payments”。

    3. description - 权限的更多细节说明。

    User

    接着在User模型中使用EntrustUserTrait特征,示例:

    <?php
    use ZizacoEntrustTraitsEntrustUserTrait;
    class User extends Eloquent{
    use EntrustUserTrait; 
    // add this trait to your user model...
    }

    这会让与角色的关系生效,并为你的User模型增加roles(), hasRole($name), can($permission), and ability($roles, $permissions, $options)这些方法。

    不要忘记执行

    composer dump-autoload 软删除

    默认的迁移在父记录被删除时运用onDelete('cascade')子句设置以删除关联。如果由于某些原因在数据库中你无法使用级联删除, EntrustRole和EntrustPermission类以及包含时间监听器的HasRole特性可以手动地在相关数据透视表中删除记录。为了避免不小心删除数据,在模型使用软删除的情况下,时间监听器不会删除实际数据。由于Laravel事件监听器的限制,没有任何办法区分delete()和forceDelete()调用。由于这个原因,在你删除这个模型之前,你必须手动地删除任何相关的数据(除非你的数据透视表使用级联删除),例如:

    $role=Role::findOrFail(1); // 取得一个给定的角色
    // 常规删除
    $role->delete(); 
    // 这无论如何都会工作
    // 强制删除
    $role->users()->sync([]); // 删除关联数据
    $role->perms()->sync([]); // 删除关联数据
    $role->forceDelete(); // 现在强制删除都会起作用,不管透视表是够有级联删除

    用法

    概念

    从创建下面的角色S和权限S开始:

    $owner=newRole();
    $owner->name='owner';
    $owner->display_name='Project Owner'; // optional
    $owner->description='User is the owner of a given project'; // optional
    $owner->save();
    $admin=newRole();
    $admin->name='admin';
    $admin->display_name='User Administrator'; // optional
    $admin->description='User is allowed to manage and edit other users'; // optional
    $admin->save();

    接着,我们将两个已经创建的角色分配给用户。因为有了HasRole特性所以很容易:

    $user=User::where('username', '=', 'michele')->first();
    // 角色添加别名
    $user->attachRole($admin); // 参数可以是角色项目,数组或者
    // 或者 eloquent's 原来的技术
    $user->roles()->attach($admin->id); // 仅ID

    现在我们只需要给这些角色添加权限:

    $createPost=newPermission();
    $createPost->name='create-post';
    $createPost->display_name='Create Posts'; // optional
    // Allow a user to...
    $createPost->description='create new blog posts'; // optional
    $createPost->save();
    $editUser=newPermission();
    $editUser->name='edit-user';
    $editUser->display_name='Edit Users'; // optional
    // Allow a user to...
    $editUser->description='edit existing users'; // optional
    $editUser->save();
    $admin->attachPermission($createPost);// equivalent to $admin->perms()->sync(array($createPost->id));
    $owner->attachPermissions(array($createPost, $editUser));// equivalent to $owner->perms()->sync(array($createPost->id, $editUser->id));

    验证角色和权限

    现在我们就可以用简单的方法验证角色和权限:

    $user->hasRole('owner'); // false
    $user->hasRole('admin'); // true
    $user->can('edit-user'); // false
    $user->can('create-post'); // true

    hasRole()和can()都能接受一个角色和权限的数组用于验证:

    $user->hasRole(['owner', 'admin']); // true
    $user->can(['edit-user', 'create-post']); // true

    默认情况,任何角色或权限属于当前用户,方法就会返回为true。 将方法的第二个参数设置为true,就要求所有权限和角色都通过才能验证成功

    $user->hasRole(['owner', 'admin']); // true
    $user->hasRole(['owner', 'admin'], true); // false, 用户并没有admin角色
    $user->can(['edit-user', 'create-post']); // true
    $user->can(['edit-user', 'create-post'], true); // false, 用户没有edit-user权限

    你可以随意为每个用户分配任意多的角色,反之亦然。

    Entrust为当前已经登录的用户准备了hasRole()和can()的快捷方式

    Entrust::hasRole('role-name');
    Entrust::can('permission-name');
    // 等价于
    Auth::user()->hasRole('role-name');
    Auth::user()->can('permission-name);

    你也可以使用占位符(通配符)验证任何符合条件的权限:

    // 匹配任意的admin权限
    $user->can("admin.*"); // true
    // 匹配任意关于用户的权限
    $user->can("*_users"); // true

    用户可用性

    更多高级验证可以使用ability函数。它有三个参数(roles,permissions,options):

    1. roles 一组用于验证的roles

    2. permissions 一组用于验证的peimissions

    roles和peimissions变量可以是一组逗号分割的字符串或数组:

    $user->ability(array('admin', 'owner'), array('create-post', 'edit-user'));
    // or
    $user->ability('admin,owner', 'create-post,edit-user');

    这可以同时检查用户是否提供角色和权限。在这个例子中,只有当用户是admin并且拥有create-post选前才会返回true.

    第三个参数是一个可选数组:

    $options = array(
    'validate_all' => true | false (Default: false),
    'return_type' => boolean | array | both (Default: boolean)
    );

    1. validate_all 这是一个boolean值用于设置是否验证所有制都为true,或者当至少一个角色或权限匹配时返回true。

    2. return_type 指定是否返回匹配值得boolean或数组,或者两者都在一个数组中,

    下面是输出的示例:

    $options = array(
    'validate_all' => true,
    'return_type' => 'both'
    );
    list($validate, $allValidations) = $user->ability(
    array('admin', 'owner'),
    array('create-post', 'edit-user'),
    $options
    );
    var_dump($validate);
    // bool(false)
    var_dump($allValidations);
    // array(4) {
    // ['role'] => bool(true)
    // ['role_2'] => bool(false)
    // ['create-post'] => bool(true)
    // ['edit-user'] => bool(false)
    // }

    Entrust为当前已登录用户准备了ability()方法的快捷方式

    Entrust::ability('admin,owner', 'create-post,edit-user');
    // 等同于
    Auth::user()->ability('admin,owner', 'create-post,edit-user');

    Blade模板

    在Blade模板中有三个模板可以使用,你的参数将会被直接传递给Entrust的函数

    @role('admin')
    <p>这里对有admin角色的用户可见. 会被翻译为 Entrust::role('admin')</p>
    @endrole
    @permission('manage-admins')
    <p>这里对给定权限的用户可见. 会被翻译为 Entrust::can('manage-admins').@can已经被laravel核心验证包使用, 所以用 @permission直接代替.</p>
    @endpermission
    @ability('admin,owner', 'create-post,edit-user')
    <p>这里对给定能力的用户可见. 会被翻译为 Entrust::ability('admin,owner', 'create-post,edit-user')</p>
    @endability

    中间件

    您可以使用中间件通过权限或角色来过滤路由和路由组:

    Route::group(['prefix' => 'admin', 'middleware' => ['role:admin']], function() {
    Route::get('/', 'AdminController@welcome');
    Route::get('/manage', ['middleware' => ['permission:manage-admins'], 'uses' => 'AdminController@manageAdmins']);
    });

    可以使用管道符号或操作符:

    'middleware'=> ['role:admin|root']

    模拟和功能化使用了多个中间件的实例:

    'middleware'=> ['permission:owner', 'permission:writer']

    更复杂的情况可以使用ability中间件,它包含三个参数:roles, permissions, validate_all

    'middleware'=> ['ability:admin|owner,create-post|edit-user,true']

    短语法路由过滤器

    使用权限或角色过滤一个路由可以在你的app/Http/routes.php中使用如下代码:

    // 仅当用户角色拥有'manage_posts'权限时才可以访问admin/post路由 
    Entrust::routeNeedsPermission('admin/post*', 'create-post');
    // 仅当owner角色可以访问admin/advanced
    Entrust::routeNeedsRole('admin/advanced*', 'owner');
    // 第二份可选参数可以是权限或角色的数组
    // 用户需要满足所有角色和权限的需求才可以访问此数组
    Entrust::routeNeedsPermission('admin/post*', array('create-post', 'edit-comment'));
    Entrust::routeNeedsRole('admin/advanced*', array('owner','writer'));

    这两个方法都接受第3个参数,如果第三个参数为null就会返回一个App::abort(403)禁止访问,否则返回第三个参数,所以你可以这样使用:

    Entrust::routeNeedsRole('admin/advanced*', 'owner', Redirect::to('/home'));

    此外这两种方法还接受第4个参数,默认为true,验证所有给定的角色和权限。如果你设置为false,仅当所有权限和角色都验证失败时函数才会返回失败。这对后台程序需要允许访问多个组很有用:

    // if a user has 'create-post', 'edit-comment', or both they will have access
    Entrust::routeNeedsPermission('admin/post*', array('create-post', 'edit-comment'), null, false);
    // if a user is a member of 'owner', 'writer', or both they will have access
    Entrust::routeNeedsRole('admin/advanced*', array('owner','writer'), null, false);
    // if a user is a member of 'owner', 'writer', or both, or user has 'create-post', 'edit-comment' they will have access
    // if the 4th parameter is true then the user must be a member of Role and must have Permission
    Entrust::routeNeedsRoleOrPermission(
    'admin/advanced*',
    array('owner', 'writer'),
    array('create-post', 'edit-comment'),
    null,
    false
    );

    路由过滤

    Entrust 的角色/权限过滤可以使用Facade:

    Route::filter('manage_posts', function()
    {
    // check the current user
    if (!Entrust::can('create-post')) {
    return Redirect::to('admin');
    }
    });
    // only users with roles that have the 'manage_posts' permission will be able to access any admin/post route
    Route::when('admin/post*', 'manage_posts');

    使用过滤验证角色:

    Route::filter('owner_role', function()
    {
    // check the current user
    if (!Entrust::hasRole('Owner')) {
    App::abort(403);
    }
    });
    // only owners will have access to routes within admin/advanced
    Route::when('admin/advanced*', 'owner_role');

  • 相关阅读:
    Drawable、Bitmap、byte[]之间的转换
    关于java.lang.IllegalArgumentException: View not attached to window manager 错误的分析
    Android ListView使用BaseAdapter与ListView的优化
    Ubuntu, using svn from terminal
    Ubuntu 12.04(64位)上搭建android 开发环境 (ADT 、android-studio)
    Widget改变大小
    android4.0中实现AppWidget集合
    android 中 AppWidget 的 ListView 的实现
    解决IllegalStateException: Can not perform this action after onSaveInstanceState
    Drawable和Bitmap转换
  • 原文地址:https://www.cnblogs.com/2881064178dinfeng/p/6212087.html
Copyright © 2011-2022 走看看