목차
1、简介
2、定义权限(Abilities)
3、检查权限(Abilities)
通过 Gate 门面
通过 User模型
在  Blade  模板引擎中检查
在表单请求中检查
4、策略类(Policies)
创建策略类
编写策略类
检查策略
5、 控制器授权
백엔드 개발 PHP 튜토리얼 [ Laravel 5.2 文档 ] 服务 -- 用户授权

[ Laravel 5.2 文档 ] 服务 -- 用户授权

Jun 23, 2016 pm 01:18 PM

1、简介

除了提供开箱即用的认证服务之外,Laravel还提供了一个简单的方式来管理授权逻辑以便控制对资源的访问权限。在 Laravel 中,有多种方法和辅助函数来协助你管理授权逻辑,本文档将会一一覆盖这些方法。

2、定义权限(Abilities)

判断用户是否有权限执行给定动作的最简单方式就是使用 Illuminate\Auth\Access\Gate类来定义一个“权限”。我们在 AuthServiceProvider中定义所有权限,例如,我们来定义一个接收当前 User和 Post 模型的 update-post权限,在该权限中,我们判断用户 id是否和文章的 user_id匹配:

<?phpnamespace App\Providers;use Illuminate\Contracts\Auth\Access\Gate as GateContract;use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;class AuthServiceProvider extends ServiceProvider{    /**     * 注册应用所有的认证/授权服务.     *     * @param  \Illuminate\Contracts\Auth\Access\Gate  $gate     * @return void     */    public function boot(GateContract $gate)    {        parent::registerPolicies($gate);        $gate->define('update-post', function ($user, $post) {            return $user->id === $post->user_id;        });    }}
로그인 후 복사

注意我们并没有检查给定 $user是否为 NULL,当用户未经过登录认证或者用户没有通过 forUser方法指定, Gate会自动为所有权限返回 false。

基于类的权限

除了注册授权回调闭包之外,还可以通过传递包含权限类名和类方法的方式来注册权限方法,当需要的时候,该类会通过服务容器进行解析:

$gate->define('update-post', 'PostPolicy@update');
로그인 후 복사

拦截认证检查

有时候,你可能希望对指定用户授予所有权限,在这种场景中,需要使用 before方法定义一个在所有其他授权检查之前运行的回调:

$gate->before(function ($user, $ability) {    if ($user->isSuperAdmin()) {        return true;    }});
로그인 후 복사
로그인 후 복사

如果 before回调返回一个非空结果,那么该结果则会被当做检查的结果。

你也可以使用 after方法定义一个在所有其他授权检查之后运行的回调,所不同的是,在 after回调中你不能编辑授权检查的结果:

$gate->after(function ($user, $ability, $result, $arguments) {    //});
로그인 후 복사

3、检查权限(Abilities)

通过 Gate 门面

权限定义好之后,可以使用多种方式来“检查”。首先,可以使用 Gate 门面的 check, allows, 或者 denies方法。所有这些方法都接收权限名和传递给该权限回调的参数作为参数。你不需要传递当前用户到这些方法,因为 Gate会自动附加当前用户到传递给回调的参数,因此,当检查我们之前定义的 update-post权限时,我们只需要传递一个 Post实例到 denies方法:

<?phpnamespace App\Http\Controllers;use Gate;use App\User;use App\Post;use App\Http\Controllers\Controller;class PostController extends Controller{    /**     * 更新给定文章     *     * @param  int  $id     * @return Response     */    public function update($id)    {        $post = Post::findOrFail($id);        if (Gate::denies('update-post', $post)) {            abort(403);        }        // 更新文章...    }}
로그인 후 복사

当然, allows方法和 denies方法是相对的,如果动作被授权会返回 true, check方法是 allows方法的别名。

为指定用户检查权限

如果你想要使用 Gate门面判断非当前用户是否有权限,可以使用 forUser方法:

if (Gate::forUser($user)->allows('update-post', $post)) {    //}
로그인 후 복사

传递多个参数

当然,权限回调还可以接收多个参数:

Gate::define('delete-comment', function ($user, $post, $comment) {    //});
로그인 후 복사

如果权限需要多个参数,简单传递参数数组到 Gate方法:

if (Gate::allows('delete-comment', [$post, $comment])) {    //}
로그인 후 복사

通过 User模型

还可以通过 User模型实例来检查权限。默认情况下,Laravel 的 App\User模型使用一个 Authorizabletrait来提供两种方法: can和 cannot。这两个方法的功能和 Gate门面上的 allows和 denies方法类似。因此,使用我们前面的例子,可以修改代码如下:

<?phpnamespace App\Http\Controllers;use App\Post;use Illuminate\Http\Request;use App\Http\Controllers\Controller;class PostController extends Controller{    /**     * 更新给定文章     *     * @param  \Illuminate\Http\Request  $request     * @param  int  $id     * @return Response     */    public function update(Request $request, $id)    {        $post = Post::findOrFail($id);        if ($request->user()->cannot('update-post', $post)) {            abort(403);        }        // 更新文章...    }}
로그인 후 복사

当然, can方法和 cannot方法相反:

if ($request->user()->can('update-post', $post)) {    // 更新文章...}
로그인 후 복사

Blade 模板引擎中检查

为了方便,Laravel 提供了 Blade 指令 @can来快速检查当前用户是否有指定权限。例如:

<a href="/post/{{ $post->id }}">View Post</a>@can('update-post', $post)    <a href="/post/{{ $post->id }}/edit">Edit Post</a>@endcan
로그인 후 복사

你还可以将 @can指令和 @else指令联合起来使用:

@can('update-post', $post)    <!-- The Current User Can Update The Post -->@else    <!-- The Current User Can't Update The Post -->@endcan
로그인 후 복사

在表单请求中检查

你还可以选择在表单请求的 authorize方法中使用 Gate定义的权限。例如:

/** * 判断请求用户是否经过授权 * * @return bool */public function authorize(){    $postId = $this->route('post');    return Gate::allows('update', Post::findOrFail($postId));}
로그인 후 복사

4、策略类(Policies)

创建策略类

由于在 AuthServiceProvider中定义所有的授权逻辑将会变得越来越臃肿笨重,尤其是在大型应用中,所以 Laravel 允许你将授权逻辑分割到多个“策略”类中,策略类是原生的PHP类,基于授权资源对授权逻辑进行分组。

首先,让我们生成一个策略类来管理对 Post模型的授权,你可以使用 Artisan 命令 make:policy来生成该策略类。生成的策略类位于 app/Policies目录:

php artisan make:policy PostPolicy
로그인 후 복사

注册策略类

策略类生成后我们需要将其注册到 Gate类。 AuthServiceProvider包含了一个 policies属性来映射实体及管理该实体的策略类。因此,我们指定 Post模型的策略类是 PostPolicy:

<?phpnamespace App\Providers;use App\Post;use App\Policies\PostPolicy;use Illuminate\Contracts\Auth\Access\Gate as GateContract;use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;class AuthServiceProvider extends ServiceProvider{    /**     * 应用的策略映射     *     * @var array     */    protected $policies = [        Post::class => PostPolicy::class,    ];    /**     * 注册所有应用认证/授权服务     *     * @param \Illuminate\Contracts\Auth\Access\Gate $gate     * @return void     */    public function boot(GateContract $gate)    {        $this->registerPolicies($gate);    }}
로그인 후 복사

编写策略类

策略类生成和注册后,我们可以为授权的每个权限添加方法。例如,我们在 PostPolicy中定义一个 update方法,该方法判断给定 User是否可以更新某个 Post:

<?phpnamespace App\Policies;use App\User;use App\Post;class PostPolicy{    /**     * 判断给定文章是否可以被给定用户更新     *     * @param  \App\User  $user     * @param  \App\Post  $post     * @return bool     */    public function update(User $user, Post $post)    {        return $user->id === $post->user_id;    }}
로그인 후 복사

你可以继续在策略类中为授权的权限定义更多需要的方法,例如,你可以定义 show, destroy, 或者 addComment方法来认证多个 Post动作。

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

拦截所有检查

有时候,你可能希望对指定用户授予所有权限,在这种场景中,需要使用 before方法定义一个在所有其他授权检查之前运行的回调:

$gate->before(function ($user, $ability) {    if ($user->isSuperAdmin()) {        return true;    }});
로그인 후 복사
로그인 후 복사

如果 before回调返回一个非空结果,那么该结果则会被当做检查的结果。

检查策略

策略类方法的调用方式和基于授权回调的闭包一样,你可以使用 Gate门面, User模型, @can指令或者辅助函数 policy。

通过 Gate 门面

Gate将会自动通过检测传递过来的类参数来判断使用哪一个策略类,因此,如果传递一个 Post实例给 denies方法,相应的, Gate会使用 PostPolicy来进行动作授权:

<?phpnamespace App\Http\Controllers;use Gate;use App\User;use App\Post;use App\Http\Controllers\Controller;class PostController extends Controller{    /**     * 更新给定文章     *     * @param  int  $id     * @return Response     */    public function update($id)    {        $post = Post::findOrFail($id);        if (Gate::denies('update', $post)) {            abort(403);        }        // 更新文章...    }}
로그인 후 복사

通过 User 模型

User模型的 cancannot 方法将会自动使用给定参数中有效的策略类。这些方法提供了便利的方式来为应用接收到的任意 User 实例进行授权:

if ($user->can('update', $post)) {    //}if ($user->cannot('update', $post)) {    //}
로그인 후 복사

在 Blade 模板中使用

类似的,Blade 指令 @can将会使用参数中有效的策略类:

@can('update', $post)    <!-- The Current User Can Update The Post -->@endcan
로그인 후 복사

通过辅助函数 policy

全局的辅助函数 policy用于为给定类实例接收策略类。例如,我们可以传递一个 Post实例给帮助函数 policy来获取相应的 PostPolicy类的实例:

if (policy($post)->update($user, $post)) {    //}
로그인 후 복사

5、 控制器授权

默认情况下,Laravel 自带的控制器基类 App\Http\Controllers\Controller使用了 AuthorizesRequeststrait,该 trait 提供了可用于快速授权给定动作的 authorize方法,如果授权不通过,则抛出 HttpException异常。

该 authorize方法和其他多种授权方法使用方法一致,例如 Gate::allows和 $user->can()。因此,我们可以这样使用 authorize方法快速授权更新 Post的请求:

<?phpnamespace App\Http\Controllers;use App\Post;use App\Http\Controllers\Controller;class PostController extends Controller{    /**     * 更新给定文章     *     * @param  int  $id     * @return Response     */    public function update($id)    {        $post = Post::findOrFail($id);        $this->authorize('update', $post);        // 更新文章...    }}
로그인 후 복사

如果授权成功,控制器继续正常执行;然而,如果 authorize方法判断该动作授权失败,将会抛出 HttpException异常并生成带 403 Not Authorized状态码的HTTP响应。正如你所看到的, authorize方法是一个授权动作、抛出异常的便捷方法。

AuthorizesRequeststrait还提供了 authorizeForUser方法用于授权非当前用户:

$this->authorizeForUser($user, 'update', $post);
로그인 후 복사

自动判断策略类方法

通常,一个策略类方法对应一个控制器上的方法,例如,在上面的 update方法中,控制器方法和策略类方法共享同一个方法名: update。

正是因为这个原因,Laravel 允许你简单传递实例参数到 authorize方法,被授权的权限将会自动基于调用的方法名进行判断。在本例中,由于 authorize在控制器的 update方法中被调用,那么对应的, PostPolicy上 update方法将会被调用:

/** * 更新给定文章 * * @param  int  $id * @return Response */public function update($id){    $post = Post::findOrFail($id);    $this->authorize($post);    // 更新文章...}
로그인 후 복사
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Laravel의 플래시 세션 데이터로 작업합니다 Laravel의 플래시 세션 데이터로 작업합니다 Mar 12, 2025 pm 05:08 PM

Laravel은 직관적 인 플래시 방법을 사용하여 임시 세션 데이터 처리를 단순화합니다. 응용 프로그램에 간단한 메시지, 경고 또는 알림을 표시하는 데 적합합니다. 데이터는 기본적으로 후속 요청에만 지속됩니다. $ 요청-

PHP의 컬 : REST API에서 PHP Curl Extension 사용 방법 PHP의 컬 : REST API에서 PHP Curl Extension 사용 방법 Mar 14, 2025 am 11:42 AM

PHP 클라이언트 URL (CURL) 확장자는 개발자를위한 강력한 도구이며 원격 서버 및 REST API와의 원활한 상호 작용을 가능하게합니다. PHP CURL은 존경받는 다중 프로모토콜 파일 전송 라이브러리 인 Libcurl을 활용하여 효율적인 execu를 용이하게합니다.

Laravel 테스트에서 단순화 된 HTTP 응답 조롱 Laravel 테스트에서 단순화 된 HTTP 응답 조롱 Mar 12, 2025 pm 05:09 PM

Laravel은 간결한 HTTP 응답 시뮬레이션 구문을 제공하여 HTTP 상호 작용 테스트를 단순화합니다. 이 접근법은 테스트 시뮬레이션을보다 직관적으로 만들면서 코드 중복성을 크게 줄입니다. 기본 구현은 다양한 응답 유형 단축키를 제공합니다. Illuminate \ support \ Facades \ http를 사용하십시오. http :: 가짜 ([ 'google.com'=> ​​'Hello World', 'github.com'=> ​​[ 'foo'=> 'bar'], 'forge.laravel.com'=>

Codecanyon에서 12 개의 최고의 PHP 채팅 스크립트 Codecanyon에서 12 개의 최고의 PHP 채팅 스크립트 Mar 13, 2025 pm 12:08 PM

고객의 가장 긴급한 문제에 실시간 인스턴트 솔루션을 제공하고 싶습니까? 라이브 채팅을 통해 고객과 실시간 대화를 나누고 문제를 즉시 해결할 수 있습니다. 그것은 당신이 당신의 관습에 더 빠른 서비스를 제공 할 수 있도록합니다.

PHP에서 늦은 정적 결합의 개념을 설명하십시오. PHP에서 늦은 정적 결합의 개념을 설명하십시오. Mar 21, 2025 pm 01:33 PM

기사는 PHP 5.3에 도입 된 PHP의 LSB (Late STATIC BING)에 대해 논의하여 정적 방법의 런타임 해상도가보다 유연한 상속을 요구할 수있게한다. LSB의 실제 응용 프로그램 및 잠재적 성능

프레임 워크 사용자 정의/확장 : 사용자 정의 기능을 추가하는 방법. 프레임 워크 사용자 정의/확장 : 사용자 정의 기능을 추가하는 방법. Mar 28, 2025 pm 05:12 PM

이 기사에서는 프레임 워크에 사용자 정의 기능 추가, 아키텍처 이해, 확장 지점 식별 및 통합 및 디버깅을위한 모범 사례에 중점을 둡니다.

PHP의 CURL 라이브러리를 사용하여 JSON 데이터가 포함 된 게시물 요청을 보내는 방법은 무엇입니까? PHP의 CURL 라이브러리를 사용하여 JSON 데이터가 포함 된 게시물 요청을 보내는 방법은 무엇입니까? Apr 01, 2025 pm 03:12 PM

PHP 개발에서 PHP의 CURL 라이브러리를 사용하여 JSON 데이터를 보내면 종종 외부 API와 상호 작용해야합니다. 일반적인 방법 중 하나는 컬 라이브러리를 사용하여 게시물을 보내는 것입니다 ...

See all articles