Table des matières
1、简介
2、定义权限(Abilities)
3、检查权限(Abilities)
通过 Gate 门面
通过 User模型
在  Blade  模板引擎中检查
在表单请求中检查
4、策略类(Policies)
创建策略类
编写策略类
检查策略
5、 控制器授权
Maison développement back-end tutoriel 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;        });    }}
Copier après la connexion

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

基于类的权限

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

$gate->define('update-post', 'PostPolicy@update');
Copier après la connexion

拦截认证检查

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

$gate->before(function ($user, $ability) {    if ($user->isSuperAdmin()) {        return true;    }});
Copier après la connexion
Copier après la connexion

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

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

$gate->after(function ($user, $ability, $result, $arguments) {    //});
Copier après la connexion

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);        }        // 更新文章...    }}
Copier après la connexion

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

为指定用户检查权限

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

if (Gate::forUser($user)->allows('update-post', $post)) {    //}
Copier après la connexion

传递多个参数

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

Gate::define('delete-comment', function ($user, $post, $comment) {    //});
Copier après la connexion

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

if (Gate::allows('delete-comment', [$post, $comment])) {    //}
Copier après la connexion

通过 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);        }        // 更新文章...    }}
Copier après la connexion

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

if ($request->user()->can('update-post', $post)) {    // 更新文章...}
Copier après la connexion

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
Copier après la connexion

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

@can('update-post', $post)    <!-- The Current User Can Update The Post -->@else    <!-- The Current User Can't Update The Post -->@endcan
Copier après la connexion

在表单请求中检查

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

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

4、策略类(Policies)

创建策略类

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

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

php artisan make:policy PostPolicy
Copier après la connexion

注册策略类

策略类生成后我们需要将其注册到 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);    }}
Copier après la connexion

编写策略类

策略类生成和注册后,我们可以为授权的每个权限添加方法。例如,我们在 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;    }}
Copier après la connexion

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

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

拦截所有检查

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

$gate->before(function ($user, $ability) {    if ($user->isSuperAdmin()) {        return true;    }});
Copier après la connexion
Copier après la connexion

如果 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);        }        // 更新文章...    }}
Copier après la connexion

通过 User 模型

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

if ($user->can('update', $post)) {    //}if ($user->cannot('update', $post)) {    //}
Copier après la connexion

在 Blade 模板中使用

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

@can('update', $post)    <!-- The Current User Can Update The Post -->@endcan
Copier après la connexion

通过辅助函数 policy

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

if (policy($post)->update($user, $post)) {    //}
Copier après la connexion

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);        // 更新文章...    }}
Copier après la connexion

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

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

$this->authorizeForUser($user, 'update', $post);
Copier après la connexion

自动判断策略类方法

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

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

/** * 更新给定文章 * * @param  int  $id * @return Response */public function update($id){    $post = Post::findOrFail($id);    $this->authorize($post);    // 更新文章...}
Copier après la connexion
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Travailler avec les données de session Flash dans Laravel Travailler avec les données de session Flash dans Laravel Mar 12, 2025 pm 05:08 PM

Laravel simplifie la gestion des données de session temporaires à l'aide de ses méthodes de flash intuitives. Ceci est parfait pour afficher de brefs messages, alertes ou notifications dans votre application. Les données ne persistent que pour la demande ultérieure par défaut: $ demande-

Curl dans PHP: Comment utiliser l'extension PHP Curl dans les API REST Curl dans PHP: Comment utiliser l'extension PHP Curl dans les API REST Mar 14, 2025 am 11:42 AM

L'extension PHP Client URL (CURL) est un outil puissant pour les développeurs, permettant une interaction transparente avec des serveurs distants et des API REST. En tirant parti de Libcurl, une bibliothèque de transfert de fichiers multi-protocol très respectée, PHP Curl facilite Efficient Execu

Misque de réponse HTTP simplifié dans les tests Laravel Misque de réponse HTTP simplifié dans les tests Laravel Mar 12, 2025 pm 05:09 PM

Laravel fournit une syntaxe de simulation de réponse HTTP concise, simplifiant les tests d'interaction HTTP. Cette approche réduit considérablement la redondance du code tout en rendant votre simulation de test plus intuitive. L'implémentation de base fournit une variété de raccourcis de type de réponse: Utiliser illuminate \ support \ faades \ http; Http :: faux ([[ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

12 meilleurs scripts de chat PHP sur Codecanyon 12 meilleurs scripts de chat PHP sur Codecanyon Mar 13, 2025 pm 12:08 PM

Voulez-vous fournir des solutions instantanées en temps réel aux problèmes les plus pressants de vos clients? Le chat en direct vous permet d'avoir des conversations en temps réel avec les clients et de résoudre leurs problèmes instantanément. Il vous permet de fournir un service plus rapide à votre personnalité

Expliquez le concept de liaison statique tardive en PHP. Expliquez le concept de liaison statique tardive en PHP. Mar 21, 2025 pm 01:33 PM

L'article traite de la liaison statique tardive (LSB) dans PHP, introduite dans PHP 5.3, permettant une résolution d'exécution de la méthode statique nécessite un héritage plus flexible. Problème main: LSB vs polymorphisme traditionnel; Applications pratiques de LSB et perfo potentiel

Frameworks de personnalisation / d'extension: comment ajouter des fonctionnalités personnalisées. Frameworks de personnalisation / d'extension: comment ajouter des fonctionnalités personnalisées. Mar 28, 2025 pm 05:12 PM

L'article examine l'ajout de fonctionnalités personnalisées aux cadres, en se concentrant sur la compréhension de l'architecture, l'identification des points d'extension et les meilleures pratiques pour l'intégration et le débogage.

Comment envoyer une demande post contenant des données JSON à l'aide de la bibliothèque Curl de PHP? Comment envoyer une demande post contenant des données JSON à l'aide de la bibliothèque Curl de PHP? Apr 01, 2025 pm 03:12 PM

Envoyant des données JSON à l'aide de la bibliothèque Curl de PHP dans le développement de PHP, il est souvent nécessaire d'interagir avec les API externes. L'une des façons courantes consiste à utiliser la bibliothèque Curl pour envoyer le post� ...

See all articles