繁体   English   中英

Laravel 阻止用户编辑/查看其他用户的资源

[英]Laravel prevent users from editing/viewing other users' resources

在我的 Laravel 应用程序中,我有多个用户帐户,这些用户帐户拥有分配给他们的资源。 例如,说“付款”。 要编辑或查看付款,用户将访问/payment/edit/{payment}路线(其中payment是付款 ID)。

虽然我有一个身份验证过滤器来阻止未登录的用户访问此页面,但没有什么可以阻止的,例如,用户 1 编辑用户 2 的付款。

是否有我可以使用的过滤器来检查付款(或任何其他资源)属于哪个用户以防止此类问题?

[我正在使用 Laravel 的模型绑定,它会自动获取路由指定的模型,而不是我使用 eloquent 在控制器中获取它。]

默认情况下不存在这样的过滤器,但是您可以轻松创建一个(取决于您的数据库的设置方式)。 在 app/filters.php 中,您可以执行以下操作:

Route::filter('restrictPermission', function($route)
{
    $payment_id = $route->parameter('payment');

    if (!Auth::user()->payments()->find($payment_id)) return Redirect::to('/');
});

这会将当前登录用户的 payment_id(在您的数据库中)与传递到路由中的 {payment} 参数进行比较。 显然,根据您的数据库的设置方式(例如,如果 payment_id 在单独的表中),您需要更改条件。

然后,将过滤器应用于您的路线:

Route::get('/payment/edit/{payment}', array('before' => 'restrictPermission'));

一种方法是在每个相关查询中放置一个 where 语句。 虽然不是很漂亮,但它有效。

$payment = Payment::where('user_id', '=', Auth::user()->id)->find($id);

也可以使用如 seeARMS 建议的 url 过滤器,但我认为它不是很优雅。 嵌套此类逻辑的最合乎逻辑的位置是模型本身。 一种可能性是使用模型事件,但这只能让您选择拦截更新、插入或删除语句,而不是选择。 这在未来可能会改变。 也许您可以使用boot()事件,但我不确定这是否可行。

最后但并非最不重要的是,您可以使用查询范围

class Payment extends Eloquent {

    public function scopeAuthuser($query)
    {
        return $query->where('user_id', '=', Auth::user()->id);
    }
}

并在查询中附加范围

Payment::authuser()->find($id);

您可以在基本模型上执行此操作并从中扩展,因此您可以在所有相关模型中使用该方法。

考虑使用 Laravel 策略: https ://laravel.com/docs/6.x/authorization#policy-methods

<?php

namespace App\Policies;

use App\Post;
use App\User;

class PostPolicy
{
    /**
     * Determine if the given post can be updated by the user.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return bool
     */
    public function update(User $user, Post $post)
    {
        return $user->id === $post->user_id;
    }
}

通过策略,您可以控制登录用户是否可以编辑给定记录。

干杯!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM