【发布时间】:2020-03-26 12:31:38
【问题描述】:
我的应用程序中有资源 API。目前有 'domain.com/posts/:id' 路由,它通过 id 返回特定的帖子。所有用户都可以访问它。但我想允许用户查看帖子,只要他是该帖子的作者或编辑:
我的 post 表有 author_id 和 editor_id 列。两列都引用了用户表的 id。
用 middlware/ 解决这个问题是一种好习惯吗(只为一个路由创建中间件?)。有什么建议么 ?
【问题讨论】:
我的应用程序中有资源 API。目前有 'domain.com/posts/:id' 路由,它通过 id 返回特定的帖子。所有用户都可以访问它。但我想允许用户查看帖子,只要他是该帖子的作者或编辑:
我的 post 表有 author_id 和 editor_id 列。两列都引用了用户表的 id。
用 middlware/ 解决这个问题是一种好习惯吗(只为一个路由创建中间件?)。有什么建议么 ?
【问题讨论】:
您可以使用 laravel 提供的授权/策略或事件 Gates。
或者只是为了保持简单,
在您的 Post 模型中
public function canView()
{
return $this->author_id === auth()->id() || $this->editor_id === auth()->id();
}
在你的控制器中
public function show(Post $post)
{
//you already have the $post
if(! $post->canView()) {
// cannot view post
}
// can view post.
}
按照这种方式,您可以轻松地在整个应用程序中使用相同的事实来源进行授权,因为您可能会在整个应用程序中使用 eloquent 的实例。
如果您的逻辑更复杂,请联系Laravel's Policy
【讨论】:
这可以通过中间件或仅用户检查控制器方法来解决。这是一个关于如何在控制器方法中执行此操作的简单示例:
public function view(Request $request, Post $post) {
// Currently logged in user.
$user = auth()->user();
// Check if the current user is either the author or editor.
if ($user->id == $post->author_id || $user->id == $post->editor_id) {
// Your controller logic.
}
abort(403);
}
编辑:我建议您将路由模式更改为domain.com/posts/:post,这样您就可以在控制器方法中使用路由模型绑定。
【讨论】: