【问题标题】:Unable to get Policies working in Laravel 5.3无法在 Laravel 5.3 中使用策略
【发布时间】:2017-01-18 12:55:12
【问题描述】:

我一直在关注 Laravel 授权文档,试图通过使用策略来构建“用户是否允许这样做”功能,但我无法让它工作。我不断收到This action is unauthorized,我也尝试过使用路由中间件。

PagePolicy.php:

namespace App\Policies;

use App\Models\User;
use App\Models\Page;

use Illuminate\Auth\Access\HandlesAuthorization;

class PagePolicy
{
    use HandlesAuthorization;

    /**
     * Determine whether the user can view the page.
     *
     * @param  App\Models\User  $user
     * @param  App\Models\Page  $page
     * @return mixed
     */
    public function view(User $user, Page $page)
    {
        return $user->id === $page->user_id;
    }

    /**
     * Determine whether the user can create pages.
     *
     * @param  App\Models\User  $user
     * @return mixed
     */
    public function create(User $user)
    {

    }

    /**
     * Determine whether the user can update the page.
     *
     * @param  App\Models\User  $user
     * @param  App\Models\Page  $page
     * @return mixed
     */
    public function update(User $user, Page $page)
    {
        //
    }

    /**
     * Determine whether the user can delete the page.
     *
     * @param  App\Models\User  $user
     * @param  App\Models\Page  $page
     * @return mixed
     */
    public function delete(User $user, Page $page)
    {
        //
    }
}

PageController.php:

namespace App\Http\Controllers;

use Auth;
use Carbon\Carbon;

use App\Models\Page;

use App\Http\Requests\PageRequest;

class PageController extends ApiController
{
    public function createNewPage(PageRequest $request)
    {
        $this->authorize('create', Page::class);

        $request->merge([
            'user_id' => Auth::id(),
            'published_at' => Carbon::now(),
        ]);

        if (Page::create($request->all())) {
            return response()->json('success', 201);
        }

        return response()->json('error', 500);
    }

}

AuthServiceProvidor.php:

namespace App\Providers;

use App\Models\Page;
use App\Policies\PagePolicy;

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 = [
        Page::class => PagePolicy::class,
    ];

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

        //
    }
}

【问题讨论】:

  • 您确定这些 ID 匹配吗?
  • 是的。我以 auth->id = 1 和 page->user_id = 1 身份登录
  • 策略方法中的 dd() 怎么样?所以你可以看看它是否真的被调用了(并且对象是你期望的对象)
  • @alvaric 的回答应该是正确的。您需要将策略中的“视图”方法的代码放入您在控制器中实际调用的“创建”方法
  • 感谢您的回复。我添加了代码 view() 以查看是否可以使其正常工作,但这不是(未授权),而且对我来说,在 create 中添加相同的代码是没有意义的,因为没有 user_id 直到页面已创建。文档显示 create() 方法为空laravel.com/docs/5.3/authorization#writing-policies,所以我也这样做了。这就是我感到困惑的地方。此外,我在控制器和策略中尝试添加 dd() 并在触发之前获取未经授权的错误的最佳位置在哪里。

标签: php laravel laravel-5 authorization policy


【解决方案1】:

当前代码:

protected $policies = [
    Task::class => TaskPolicy::class,
];

解决方案代码:

protected $policies = [
    'App\Task' => 'App\Policies\TaskPolicy',
];

我在关注 Laravel 网站上的 Intermediate Task List Tutorial 时遇到了同样的问题。

解决方案实际上存在于Github code for this tutorial中。

【讨论】:

  • 这基本上是一样的,如果这不起作用,你一定搞砸了。
  • Laravel 在后台将 Task::class 转换为 'App\Task',所以它是一回事!
【解决方案2】:

我设法弄明白了。我没有使用路由模型绑定。所以我在页面调用之后添加了authorize(),并使用了$page变量而不是Page::class

public function update(PageUpdateRequest $request, $pageSlug)
{
    $page = Page::where(['user_id' => Auth::id(), 'slug' => $pageSlug])->first();
    $this->authorize('update', $page);
    $page->update($request->all());
    return fractal()->item($page, new PageTransformer())->toArray();
}

【讨论】:

  • 您能详细说明一下吗?我不确定你做了什么。
  • @Dubby 你有想过这个吗?我也遇到了同样的问题。
【解决方案3】:

我认为问题不在于您的政策,而在于您的 PageRequest 课程。确保 App\Http\Requests\PageRequest 类中的 authorize() 方法返回 true

class PageRequest extends FormRequest
{
    /**
    * Determine if the user is authorized to make this request.
    *
    * @return bool
    */
    public function authorize()
    {
        return true; // you can also check the authorization using PagePolicy here
    }
}

【讨论】:

    【解决方案4】:

    我并不完全清楚您正在尝试授权哪个操作,因为您已经在控制器中提供了 create 调用,但只提供了用于查看页面的策略检查。话虽如此,我肯定会对您尝试进行类型比较的值进行 var_dump/dd 以验证它们是否属于同一类型。如果有任何内容被显式转换,则可能会导致某些将整数作为字符串返回的数据库驱动程序出现问题。

    【讨论】:

    • 嗨。我在上面 Fabian 的回复下添加了评论。不确定这是否能稍微解决问题。
    • 只是为了添加到 Fabian 的 cmets 并可能澄清情况,Laravel 将寻找与传递给 "$this->authorize" 的第一个参数同名的函数。如果进行此更改不能解决问题,请随时更新您最初发布的代码以显示最新/最佳版本,以帮助进一步诊断问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-30
    • 2019-11-16
    • 1970-01-01
    • 2017-02-05
    • 2021-06-16
    • 1970-01-01
    相关资源
    最近更新 更多