Laravel 5:如果用户是帖子的所有者或论坛类别的所有者,则允许用户编辑帖子

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32951025/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 12:27:21  来源:igfitidea点击:

Laravel 5: allow user to edit post if he's the owner of the post or the owner of the forum category

phpmysqllaravellaravel-5eloquent

提问by Halnex

So far I was able to allow the user to edit his own posts but whenever I through the if he's owner of the subreddit/categorycondition, it stops working altogether.

到目前为止,我能够允许用户编辑他自己的帖子,但是每当我通过if he's owner of the subreddit/category条件时,它就完全停止工作。

I have these 3 table

我有这 3 张桌子

Users: id, name, email...
Subreddits: id, name, user_id...
Posts: id, link, title, user_id, subreddit_id...

This is the edit()method in PostsController.php

这是edit()方法PostsController.php

public function edit(Post $post, Subreddit $subreddit)
    {
        if(Auth::id() !== $post->user_id) {
            return view('home')->withErrors('You cannot do that');
        } else {
            return view('post/edit')->with('post', $post)->with('subreddit', $subreddit);
        }
    }

And this is the view

这是视图

@if(Auth::id() == $post->user_id)
      <a href="{{ action('PostsController@edit', [$post->id]) }}">Edit</a>
@endif

This works fine, it only checks if the logged in user_id is the same as the posts's user_id and updating goes through.

这工作正常,它只检查登录的 user_id 是否与帖子的 user_id 相同,并且更新通过。

But if I added if(Auth::id() == $subreddit->user_id)it stops working. It displays the "Edit" link on the view on all the posts but clicking on any of them gives me the validation error You cannot do thateven for posts that I own.

但如果我添加if(Auth::id() == $subreddit->user_id)它停止工作。它在所有帖子的视图上显示“编辑”链接,但单击其中任何一个都会给我带来验证错误,You cannot do that即使对于我拥有的帖子也是如此。

So how can I check if the users is the owner of the article OR the owner of the category to display and allow EDIT?

那么如何检查用户是文章的所有者还是类别的所有者以显示并允许编辑?

Updated method with $subreddit->user_id

更新方法 $subreddit->user_id

public function edit(Post $post, Subreddit $subreddit)
    {
        if(Auth::id() == $post->user_id || Auth::id() == $subreddit->user_id) {
            return view('post/edit')->with('post', $post)->with('subreddit', $subreddit);
        } else {
            return view('home')->withErrors('You cannot do that');
        }
    }

View

看法

@if(Auth::id() == $post->user_id || Auth::id() == $subreddit->user_id)
      <a href="{{ action('PostsController@edit', [$post->id]) }}">Edit</a>
@endif

This will allow me to edit my own posts but will still give me the validation error You cannot do thaton posts in my own forum category/subreddit.

这将允许我编辑我自己的帖子,但仍然会给我You cannot do that在我自己的论坛类别/subreddit 中的帖子的验证错误。

This is the Gatepolicies that I've tried but it also didn't work

这是Gate我尝试过的政策,但也没有奏效

class AuthServiceProvider extends ServiceProvider
{
    // Authorizations and Permissions
    public function boot(GateContract $gate)
    {
        parent::registerPolicies($gate);

        $gate->define('update-post', function ($user, $post) {
                return $user->id === $post->user_id;
        });

        $gate->define('mod-update-post', function ($user, $subreddit) {
            return $user->id === $subreddit->user_id;
        });
    }

PostsController.php

帖子控制器.php

public function edit(Post $post, Subreddit $subreddit, User $user)
    {
        if(Gate::denies('update-post', $post) && Gate::denies('mod-update-post', $subreddit)) {
        return view('home')->withErrors('You cannot do that');
    } else {
        return view('post/edit')->with('post', $post)->with('subreddit', $subreddit);
    }
    }

View

看法

@can('update-post', $post)
     <a href="{{ action('PostsController@edit', [$post->id]) }}">Edit</a>
@endcan

With the above code, I am finally able to edit posts if 'update-post' is true but I cannot check if mod-update-postis also true, I keep receiving the validation error You cannot do this

使用上面的代码,如果“update-post”为真,我终于可以编辑帖子,但我无法检查是否mod-update-post也为真,我一直收到验证错误You cannot do this

dd($subreddit)inside edit() method shows an empty array. https://cryptbin.com/x6V6wX#26810f755a62f6c8837c0c0fe0371dcf

dd($subreddit)在 edit() 方法内部显示一个空数组。https://cryptbin.com/x6V6wX#26810f755a62f6c8837c0c0fe0371dcf

EDIT: I think I've solved it. I used $post->subreddit->user->idinstead of $subreddit->user_idbecause that was returning null. And now it all seems to work based on if posts belongs to user or user is forum owner.

编辑:我想我已经解决了。我使用$post->subreddit->user->id而不是$subreddit->user_id因为它返回空值。现在这一切似乎都基于帖子属于用户还是用户是论坛所有者。

But the edit link on the view still shows whether or not I have access. I am unable to double check for update-postand mod-update-postsimultaneously. and using @can('update-post', $post)only works once, I cannot double check that.

但是视图上的编辑链接仍然显示我是否有权访问。我无法同时仔细检查update-postmod-update-post。并且@can('update-post', $post)只使用一次,我无法仔细检查。

采纳答案by Martin Bean

So how can I check if the users is the owner of the article OR the owner of the category to display and allow EDIT?

那么如何检查用户是文章的所有者还是类别的所有者以显示并允许编辑?

Use Laravel's new authorization component.

使用 Laravel 的新授权组件

EDIT:I think you're misunderstanding how authorization should be used. It should be used to check if the current usercan perform an action (or not). Therefore, you don't want to be defining multiple methods for different users types.

编辑:我认为您误解了应如何使用授权。它应该用于检查当前用户是否可以执行操作(或不执行)。因此,您不想为不同的用户类型定义多种方法。

Take editing a post for example. There's the name of your authorization check: @can('edit', $post). You don't need to define a different one for regular users, and another for moderators. Just add the logic to your edit post method:

以编辑帖子为例。这是您的授权检查的名称:@can('edit', $post)。您不需要为普通用户定义不同的一个,为版主定义另一个。只需将逻辑添加到您的编辑帖子方法中:

class PostPolicy
{
    public function edit(User $user, Post $post)
    {
        // If user is administrator, then can edit any post
        if ($user->isModerator()) {
            return true;
        }

        // Check if user is the post author
        if ($user->id === $post->author_id) {
            return true;
        }

        return false;
    }
}

As you can see, I'm doing the different checks in the same method, so in your Blade template you can just do this:

如您所见,我正在使用相同的方法进行不同的检查,因此在您的 Blade 模板中,您可以这样做:

@can('edit', $post)
    <a href="{{ route('post.edit', $post->getRouteKey()) }}">Edit post</a>
@endcan

Hope this clears things up.

希望这能解决问题。

回答by leo

Alternative technique (maybe a little bit simpler) is described here:

此处描述了替代技术(可能更简单一点):

https://laracasts.com/discuss/channels/laravel/dont-allow-user-to-change-others-posts

https://laracasts.com/discuss/channels/laravel/dont-allow-user-to-change-others-posts

So the idea is to implement a subclass of Request, where you can implement validation rules, and where you can also implement an 'authorize' method.

所以想法是实现Request的一个子类,在那里你可以实现验证规则,在那里你也可以实现一个'authorize'方法。