0

0

Laravel 5.1框架中的ACL用户授权和权限检查功能的实现

不言

不言

发布时间:2018-07-31 11:48:45

|

2584人浏览过

|

来源于php中文网

原创

本篇文章给大家分享的内容是关于laravel 5.1框架中的acl用户授权及权限检查功能的实现,有一定的参考价值,希望可以帮助到有需要的朋友。

1、引言

Laravel提供的开箱即用的认证功能使得用户注册、登录、退出和密码重置变得便捷和简单。

但是如果你需要控制访问站点特定部分,或者让非管理员打开/关闭特定页面,又或者确保某些用户只能编辑自己发布的东西(如文章),那么 你就需要引入类似BeatSwitch Lock这样的工具或者自己手动编写这样的功能。我们将这样的功能称之为ACL:Access Control Lists(访问控制列表),用于定义用户基于其用户记录属性操作或查看特定事物的权限。

幸运的是,从Laravel 5.1.11开始,Laravel提供了开箱即用的授权功能用于实现上述需求,我们不再需要做任何额外工作,用就是了。

注:在开始本节之前,请参考升级指南将Laravel升级到Laravel 5.1.11,否则不能实现相关功能。

2、能做什么?

Laravel提供的开箱即用的ACL被称作Gate(这并不是一个类似Spark的产品名称,而只是一个类和门面的名称)。

使用Gate类(注入或使用Gate门面)允许我们轻松检查某个用户(当前登录用户或指定用户)是否允许操作特定事物。检查代码如下:

if (Gate::denies('update-post', $post)) {
    abort(403);
}

将这段代码放到控制器中,它将会使用定义好的规则update-post来检查当前认证用户是否有权限更新指定文章。

你还可以使用Gate::allows,该方法与denies方法相对,还可以在Blade视图模板中通过@can来使用,还有更多更多,让我们接下来一窥究竟。

3、如何使用?

Laravel ACL建立在“权限”概念之上,权限包括一个键(例如update-post)和一个返回true或false的闭包(可传入参数)。

3.1 定义权限

让我们在AuthServiceProvider中定义用户更新文章权限update-post如下:

define('update-post', function ($user, $post) {
            return $user->id === $post->user_id;
        });
    }
}

正如你所看到的,定义权限闭包的第一个参数是指定用户,如果当前用户没有通过登录认证,Gate将会自定返回false。

当然,除了闭包之外,还可以通过类方法作为第二个参数来替代闭包,该类会在容器中解析:

$gate->define('update-post', 'PostPolicy@update');

3.2 通过Gate门面检查权限

Gate提供如下方法进行权限检查:check、allows和denies,check和allows功能用法完全一样,而denies和allows功能相反。

如果你使用门面检查权限,则不需要传递用户实例,Gate门面会自动将当前用户传递进来:

if (Gate::denies('update-post', $post)) {       
    abort(403);
}

如果你在权限中定义了多个参数:

Gate::define('delete-comment', function ($user, $post, $comment) {
    //
});

则检查方法如下:

if (Gate::allows('delete-comment', [$post, $comment])) {
    //
}

如果你想检查非当前认证用户是否有权限操作,调用方法如下:

if (Gate::forUser($user)->allows('update-post', $post)) {
    //
}

3.3 使用Gate注入检查权限

和以往一样,可以注入Gate类而不是使用其门面,注入的类和你在AuthServiceProvider中一样——Illuminate\Contracts\Auth\Access\Gate:

public function somethingResolvedFromContainer(Gate $gate)
{
    if ($gate->denies('update-post')) {
        // etc.
    }
}

3.4 使用User模型检查权限

Laravel的App\User模型现在使用了Authorizabletrait,因此可以使用其提供的can和cannot方法,分别对应Gate的allows和denies方法。

所以我们也可以使用User模型来检查权限:

public function update(Request $request, $id)
{
    $post = Post::findOrFail($id);
    if ($request->user()->cannot('update-post', $post)) {
        abort(403);
    }
    // 更新文章...
}

3.5 在Blade中检查权限

千博企业网站管理系统静态HTML2009 Build 0601
千博企业网站管理系统静态HTML2009 Build 0601

千博企业网站管理系统静态HTML搜索引擎优化单语言个人版介绍:系统内置五大模块:内容的创建和获取功能、存储和管理功能、权限管理功能、访问和查询功能及信息发布功能,安全强大灵活的新闻、产品、下载、视频等基础模块结构和灵活的框架结构,便捷的频道管理功能可无限扩展网站的分类需求,打造出专业的企业信息门户网站。周密的安全策略和攻击防护,全面防止各种攻击手段,有效保证网站的安全。系统在用户资料存储和传递中,

下载

你可以在Blade中使用@can指令来检查权限:

查看文章
@can('update-post', $post)
    编辑文章
@endcan

与之相对的是@else指令:

@can('update-post', $post)
    
@else
    
@endcan

3.6 中止权限检查

如果是管理员或超级用户拥有所有权限怎么做?或者你想要为用户临时切换ACL逻辑又该当如何?

Gate提供的before方法允许你在一些特定情况下在执行其他检查前就返回,不再往下检查权限:

$gate->before(function ($user, $ability) {
    if ($user->last_name === 'Stauffer') {
        return true;
    }
});

或者使用用户自己的时候:

$gate->before(function ($user, $ability) {
    if ($user->isOwner()) {
        return true;
    }
});

3.7 策略类

随着应用逻辑越来越复杂,要处理的权限越来越多,将所有权限定义在AuthServiceProvider显然不是一个明智的做法,因此Laravel引入了策略类,策略类是一些原生的PHP类,和控制器基于资源对路由进行分组类似,策略类基于资源对权限进行分组管理。

生成策略类

可以使用如下Artisan命令生成PostPolicy策略类:

php artisan make:policy PostPolicy

生成的策略类位于app/Policies目录。

然后我们可以在AuthServiceProvider的policies属性中注册策略类:

protected $policies = [
    Post::class => PostPolicy::class,
];

下面我们编辑PostPolicy如下:

id === $post->user_id;
    }
}

注:所有策略类都通过服务容器进行解析,这意味着你可以在策略类的构造函数中类型提示任何依赖,它们将会自动被注入。

检查策略

如果为某个资源类型定义了策略类,Gate将会使用第一个参数来判断检查策略类上的哪个方法。

因此,要检查是否有权限更新某篇文章,只需要传入文章实例和update权限:

当然也可以使用User模型和Blade指令检查权限。

此外,Laravel还提供了一个全局帮助函数policy来检查权限:

if (policy($post)->update($user, $post)) {
    //
}

3.8 控制器授权

由于大多数授权都会在检查权限失败的情况下退出控制器方法,因此在控制器中检查权限有一条捷径(AuthorizesRequeststrait提供,该trait在基类控制器Controller中被使用):

authorize('update', $post);
        // 更新文章...
    }
}

和我们上面的例子一样,如果授权失败会抛出403错误。

最后,如果你的控制器方法名和策略类中的方法名相同,例如都是update,则可以省略authorize的第一个参数:

public function update($id){
    $post = Post::findOrFail($id);
    $this->authorize($post);
    // 更新文章...
}

此外,AuthorizesRequests也提供了对非当前认证用户权限检查的支持:

$this->authorizeForUser($user, 'update', $post);

相关文章推荐:

Laravel 5.1框架中如何创建自定义Artisan控制台命令

相关课程推荐:

2017年最新的五个Laravel视频教程推荐

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2513

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1596

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1488

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

952

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1415

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1234

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1445

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1306

2023.11.13

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

36

2026.01.14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号