Jadual Kandungan
1、简介
2、定义权限(Abilities)
3、检查权限(Abilities)
通过 Gate 门面
通过 User模型
在  Blade  模板引擎中检查
在表单请求中检查
4、策略类(Policies)
创建策略类
编写策略类
检查策略
5、 控制器授权
Rumah pembangunan bahagian belakang tutorial 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;        });    }}
Salin selepas log masuk

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

基于类的权限

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

$gate->define('update-post', 'PostPolicy@update');
Salin selepas log masuk

拦截认证检查

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

$gate->before(function ($user, $ability) {    if ($user->isSuperAdmin()) {        return true;    }});
Salin selepas log masuk
Salin selepas log masuk

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

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

$gate->after(function ($user, $ability, $result, $arguments) {    //});
Salin selepas log masuk

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);        }        // 更新文章...    }}
Salin selepas log masuk

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

为指定用户检查权限

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

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

传递多个参数

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

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

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

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

通过 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);        }        // 更新文章...    }}
Salin selepas log masuk

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

if ($request->user()->can('update-post', $post)) {    // 更新文章...}
Salin selepas log masuk

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
Salin selepas log masuk

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

@can('update-post', $post)    <!-- The Current User Can Update The Post -->@else    <!-- The Current User Can't Update The Post -->@endcan
Salin selepas log masuk

在表单请求中检查

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

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

4、策略类(Policies)

创建策略类

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

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

php artisan make:policy PostPolicy
Salin selepas log masuk

注册策略类

策略类生成后我们需要将其注册到 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);    }}
Salin selepas log masuk

编写策略类

策略类生成和注册后,我们可以为授权的每个权限添加方法。例如,我们在 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;    }}
Salin selepas log masuk

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

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

拦截所有检查

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

$gate->before(function ($user, $ability) {    if ($user->isSuperAdmin()) {        return true;    }});
Salin selepas log masuk
Salin selepas log masuk

如果 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);        }        // 更新文章...    }}
Salin selepas log masuk

通过 User 模型

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

if ($user->can('update', $post)) {    //}if ($user->cannot('update', $post)) {    //}
Salin selepas log masuk

在 Blade 模板中使用

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

@can('update', $post)    <!-- The Current User Can Update The Post -->@endcan
Salin selepas log masuk

通过辅助函数 policy

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

if (policy($post)->update($user, $post)) {    //}
Salin selepas log masuk

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);        // 更新文章...    }}
Salin selepas log masuk

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

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

$this->authorizeForUser($user, 'update', $post);
Salin selepas log masuk

自动判断策略类方法

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

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

/** * 更新给定文章 * * @param  int  $id * @return Response */public function update($id){    $post = Post::findOrFail($id);    $this->authorize($post);    // 更新文章...}
Salin selepas log masuk
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bekerja dengan Data Sesi Flash di Laravel Bekerja dengan Data Sesi Flash di Laravel Mar 12, 2025 pm 05:08 PM

Laravel memudahkan mengendalikan data sesi sementara menggunakan kaedah flash intuitifnya. Ini sesuai untuk memaparkan mesej ringkas, makluman, atau pemberitahuan dalam permohonan anda. Data hanya berterusan untuk permintaan seterusnya secara lalai: $ permintaan-

Curl dalam PHP: Cara Menggunakan Pelanjutan PHP Curl dalam API REST Curl dalam PHP: Cara Menggunakan Pelanjutan PHP Curl dalam API REST Mar 14, 2025 am 11:42 AM

Pelanjutan URL Pelanggan PHP (CURL) adalah alat yang berkuasa untuk pemaju, membolehkan interaksi lancar dengan pelayan jauh dan API rehat. Dengan memanfaatkan libcurl, perpustakaan pemindahan fail multi-protokol yang dihormati, php curl memudahkan execu yang cekap

Respons HTTP yang dipermudahkan dalam ujian Laravel Respons HTTP yang dipermudahkan dalam ujian Laravel Mar 12, 2025 pm 05:09 PM

Laravel menyediakan sintaks simulasi respons HTTP ringkas, memudahkan ujian interaksi HTTP. Pendekatan ini dengan ketara mengurangkan redundansi kod semasa membuat simulasi ujian anda lebih intuitif. Pelaksanaan asas menyediakan pelbagai jenis pintasan jenis tindak balas: Gunakan Illuminate \ Support \ Facades \ http; Http :: palsu ([ 'Google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

12 skrip sembang php terbaik di codecanyon 12 skrip sembang php terbaik di codecanyon Mar 13, 2025 pm 12:08 PM

Adakah anda ingin memberikan penyelesaian segera, segera kepada masalah yang paling mendesak pelanggan anda? Sembang langsung membolehkan anda mempunyai perbualan masa nyata dengan pelanggan dan menyelesaikan masalah mereka dengan serta-merta. Ia membolehkan anda memberikan perkhidmatan yang lebih pantas kepada adat anda

Terangkan konsep pengikatan statik lewat dalam PHP. Terangkan konsep pengikatan statik lewat dalam PHP. Mar 21, 2025 pm 01:33 PM

Artikel membincangkan pengikatan statik lewat (LSB) dalam PHP, yang diperkenalkan dalam Php 5.3, yang membolehkan resolusi runtime kaedah statik memerlukan lebih banyak warisan yang fleksibel. Isu: LSB vs polimorfisme tradisional; Aplikasi Praktikal LSB dan Potensi Perfo

Menyesuaikan/Memperluas Rangka Kerja: Cara Menambah Fungsi Custom. Menyesuaikan/Memperluas Rangka Kerja: Cara Menambah Fungsi Custom. Mar 28, 2025 pm 05:12 PM

Artikel ini membincangkan menambah fungsi khusus kepada kerangka kerja, memberi tumpuan kepada pemahaman seni bina, mengenal pasti titik lanjutan, dan amalan terbaik untuk integrasi dan debugging.

Bagaimana cara menghantar permintaan pos yang mengandungi data JSON menggunakan perpustakaan php curl? Bagaimana cara menghantar permintaan pos yang mengandungi data JSON menggunakan perpustakaan php curl? Apr 01, 2025 pm 03:12 PM

Menghantar data JSON menggunakan perpustakaan Curl PHP dalam pembangunan PHP, sering kali perlu berinteraksi dengan API luaran. Salah satu cara biasa ialah menggunakan perpustakaan curl untuk menghantar post ...

See all articles