如何使用JWTAuth和Laravel阻止ID访问Model?

时间:2017-09-15 16:32:11

标签: laravel laravel-5 eloquent authorization laravel-eloquent

我正在使用Laravel构建一些API端点,并且我使用JWTAuth作为授权请求的令牌提供程序。

我已经设置了保护一组正常使用的API路由:

Route::group(['prefix' => '/v1', 'middleware' => 'jwt.auth'], function() {
    Route::resource('messages', 'MessagesController');
});

Message模型属于User

我尝试使用该关系执行某些请求,同时保持请求不提供不属于该用户的数据:

  1. 获取已登录用户的消息列表
  2. 获取已登录用户的个人消息
  3. 我遇到的主要问题是如何阻止用户访问不属于他们的Message。我在我的控制器中有这个:

    public function show($message_id)
    {
        $message = Message::findOrFail($message_id);
        return $message;
    }
    

    这显然会返回Message,无论它是否属于该用户。 有关如何改进以限制访问其他用户邮件的任何建议吗?

    对于所有消息的列表,我能够在控制器中执行以下操作:

    public function index()
    {
        $user_id = Auth::User()->id;
        $messages = Message::where('user_id', $user_id)->paginate(10);
        return $messages;
    }
    

    这很有效,但我不确定这是最好的方法。也许是,但一些反馈将不胜感激。我很困惑中间件是否应该处理用户有权访问的内容,或者它是否应该成为雄辩查询的一部分?

1 个答案:

答案 0 :(得分:0)

你的问题是,

  

如何防止用户访问不属于的消息   他们。

多数民众赞成属于Authorization

您可以使用Gates授权用户,我认为这是最好的方法。你所有人的拳头都需要一个Policy对象。

<?php

namespace App\Policies;

use App\User;
use App\Message;

class MessagePolicy
{
    /**
     * Determine if the given Message can be viewed by the user.
     *
     * @param  \App\User  $user
     * @param  \App\Message  $Message
     * @return bool
     */
    public function view(User $user, Message $Message)
    {
        return $user->id === $Message->user_id;
        // Here this User's id should match with the user_id of the Massage
    }
}

你甚至可以像这样生成样板文件,

php artisan make:policy MessagePolicy --model=Message

然后您可以在AuthServiceProvider中注册,

<?php

namespace App\Providers;

use App\Message;
use App\Policies\MessagePolicy;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        Message::class => MessagePolicy::class,
    ];

    /**
     * Register any application authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Gate::define('view-message', 'MessagePolicy@view');
    }
}

在您的控制器中,您可以像这样使用它,

public function show($message_id)
{
    if (Gate::allows('view-message', Message::findOrFail($message_id)) {
        return $message;
    }
}

注意:请使用此代码段作为参考或起点,因为我尚未对其进行正确测试。但潜在的概念是正确的。将其用作伪代码。如果发现错误,请在此处更新:)