📅  最后修改于: 2023-12-03 15:02:36.036000             🧑  作者: Mango
在 Laravel 中,门和策略是一种很有用的控制访问权限的方法。门是定义访问权限的地方,策略是实现这些权限的地方。
门可以理解为在路由、控制器或任何方法中添加的中间件。它是定义访问授权的地方。
门有两种不同类型:授权门和检查门。授权门用于授权访问给定的资源或模型,检查门用于检查访问特定资源或模型的权限。
授权门用于授权或拒绝访问指定的资源或模型。在 Laravel 中,可以通过定义一个名为“policy”的类来创建授权门。这个类需要实现响应示例中所有的授权方法。以下是一个授权门的示例:
namespace App\Policies;
use App\Models\User;
use App\Models\Post;
class PostPolicy
{
/**
* Determine whether the user can view the post.
*
* @param \App\Models\User $user
* @param \App\Models\Post $post
* @return mixed
*/
public function view(User $user, Post $post)
{
return $user->id === $post->user_id;
}
/**
* Determine whether the user can create posts.
*
* @param \App\Models\User $user
* @return mixed
*/
public function create(User $user)
{
//
}
/**
* Determine whether the user can update the post.
*
* @param \App\Models\User $user
* @param \App\Models\Post $post
* @return mixed
*/
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}
/**
* Determine whether the user can delete the post.
*
* @param \App\Models\User $user
* @param \App\Models\Post $post
* @return mixed
*/
public function delete(User $user, Post $post)
{
return $user->id === $post->user_id;
}
}
在这个示例中,我们定义了一个名为 PostPolicy 的类,并实现了在示例中使用的所有授权方法。
要启动门,需要在控制器构造函数中指定策略类:
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function __construct()
{
$this->authorizeResource(Post::class, 'post');
}
// Controller methods
}
在这个控制器的构造函数中,我们使用 策略方法authorizeResource() 并传递我们想要保护的授权类 Post 和请求中资源 ID 的名称 post。
接下来,我们可以在控制器方法中使用 身份验证 辅助函数,以确保用户有权限访问该方法:
public function show(Post $post)
{
$this->authorize('view', $post);
return view('posts.show', [
'post' => $post,
]);
}
在这个示例中,我们使用 身份验证 方法 并传递 view 方法和资源 $post。 这将启动我们之前定义的 PostPolicy 类中的 view 方法,以确定用户是否有权限查看 $post。
检查门用于检查用户是否有访问资源或模型的权限。在 Laravel 中,您可以使用策略类来定义检查门。
以下是一个检查门的示例:
namespace App\Policies;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
class UserPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can update the user.
*
* @param \App\Models\User $user
* @param \App\Models\User $model
* @return mixed
*/
public function update(User $user, User $model)
{
return $user->id === $model->id;
}
}
在这个示例中,我们为 User 模型创建了一个名为 UserPolicy 的策略类。我们实现了一个 update 方法,该方法检查用户是否有更新自己帐户的权限。
在控制器或其他方法中使用这个策略类之前,我们需要在进行中注册策略。 在 app\Providers\AuthServiceProvider.php 中可以注册它:
namespace App\Providers;
use App\Models\User;
use App\Policies\UserPolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
User::class => UserPolicy::class,
];
public function boot()
{
$this->registerPolicies();
//
}
}
在这个授权服务提供程序中,我们将 UserPolicy 类与 User 模型关联的策略类注册到服务容器中。我们还需要将策略类传递给 Gate 类的策略类的静态 authorize 方法:
Gate::policy(User::class, UserPolicy::class);
现在,我们可以在需要验证用户权限的控制器或其他方法中使用 Gate 门面:
if (Gate::allows('update', $user)) {
// The user can update the user...
}
if (Gate::denies('update', $user)) {
// The user can't update the user...
}
在这个示例中,我们使用 allows 方法来确定用户是否可以更新另一个用户的帐户信息。使用 denies 方法可以实现相反的逻辑。
策略是实现授权逻辑的地方。 Laravel 的策略是用于执行授权检查的简单类。这些类包含了定义的一些方法,使我们能够检查用户是否具有访问给定资源的权限。
以下是一个策略的示例:
namespace App\Policies;
use App\Models\User;
use App\Models\Post;
class PostPolicy
{
/**
* Determine if the given post can be updated by the user.
*
* @param \App\Models\User $user
* @param \App\Models\Post $post
* @return bool
*/
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}
}
在这个示例中,我们实现了一个名为 update 的策略方法。这个方法接受一个 User 实例和一个 Post 实例,并判断是否可以更新该文章。在这个示例中,只有用户 ID 与文章的用户 ID 相同时才允许更新文章。
要使用策略,需要在使用策略的控制器内启用建筑物策略行为:
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function __construct()
{
$this->authorizeResource(Post::class, 'post');
}
// ...
}
在该示例中,我们可以看到 authorizeResource 方法将两个参数传递:一个模型类(在这种情况下,Post::class)和请求中资源参数(在此示例中为$routeKeyName)。
策略内部的资源方法将自动查找并调用,以执行相应处理逻辑。为了利用此功能,您必须遵循给定的命名约定。所需的策略方法及其相应的 HTTP 谓词如下:
需要注意的是,可以添加与您的应用程序相关的自定义方法签名。
当您不使用 {{!! $model->renderModelTable() !!}} Blade 模板渲染器时,可以通过通过手动注册资源授权来在控制器中使用策略。
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
class PostController extends Controller
{
/**
* Show the form for creating a new post.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
if (Gate::allows('create', Post::class)) {
// Do something with create permission...
}
return view('posts.create');
}
// ...
}
在 this 示例中,我们使用 allows 方法来确定当前用户是否具有创建 Post 实例的权限。如果这是情况,就做一些事情。否则,我们显示一个视图。
通过使用门和策略,在 Laravel 中可以更轻松地实现授权逻辑,并实现对资源的访问控制。 Laravel 的策略非常灵活,使我们能够实现许多各种各样的授权逻辑。