You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel用户与角色权限控制问题:编辑自身Termin触发403错误

Laravel用户授权问题:无法编辑自身创建的Termin

我需要在Laravel中实现用户与角色的授权控制,要求:

  • 每个用户仅能编辑和查看自己创建的Termin(会议)
  • 无法访问其他用户创建的Termin编辑页面,手动输入其他ID的编辑链接(如http://localhost:8000/admin/termins/1/edit)时返回403错误

但当前代码下,所有用户进入自身Termin的编辑页面都会触发403未授权错误。相关代码如下:

当前Controller代码

public function edit($id)
{
    $termin = Termin::findOrFail($id);

    $this->authorize('edit', $termin);

    // Rest of code...
}

当前Policy代码

<?php

// app/Policies/TerminPolicy.php

namespace App\Policies;

use App\User;
use App\Termin;
use Illuminate\Auth\Access\HandlesAuthorization;

class TerminPolicy
{
    use HandlesAuthorization;

    public function edit(User $user, Termin $termin)
    {
        \Log::info("User ID: {$user->id}, Created By ID: {$termin->created_by_id}");

        return $user->id === $termin->created_by_id;
    }

    public function view(User $user, Termin $termin)
    {
        return $user->id === $termin->created_by_id;
    }
}

AuthServiceProvider代码

<?php

namespace App\Providers;

use App\Policies\TerminPolicy;
use App\Role;
use App\User;
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 = [
        Termin::class => TerminPolicy::class,
    ];

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

        
        if (! app()->runningInConsole()) {
            $roles = Role::with('permission')->get();

            $permissionArray = [];
            
            foreach ($roles as $role) {
                foreach ($role->permission as $permission) {
                    $permissionArray[$permission->title][] = $role->id;
                }
            }

            foreach ($permissionArray as $title => $roles) {
                Gate::define($title, function (User $user) use ($roles) {
                    return count(array_intersect($user->role->pluck('id')->toArray(), $roles));
                });
            }

        }
    }
}

User Model代码

public function role()
{
    return $this->belongsToMany(Role::class, 'role_user');
}

// Rest of code...

问题排查与解决步骤

1. 核对字段匹配

  • 确认Termin表中存储创建者ID的字段确实是created_by_id,如果字段名是user_id或其他名称,需同步修改Policy中的判断逻辑。
  • 查看storage/logs/laravel.log中的日志输出,对比User ID和Created By ID的数值是否一致,快速定位是否是字段值不匹配导致判断失败。

2. 修复Gate与Policy的冲突

你在AuthServiceProvider中注册的自定义Gate,如果存在名为edit的权限,会直接覆盖Policy中的edit方法,导致所有者判断逻辑失效。解决方法:

  • 给权限添加前缀,比如将edit改为termin.edit,避免与Policy方法名冲突;
  • 或者在Gate定义中整合所有者判断逻辑,示例:
Gate::define('termin.edit', function (User $user, Termin $termin) {
    $hasRolePermission = count(array_intersect($user->role->pluck('id')->toArray(), $roles));
    return $hasRolePermission && $user->id === $termin->created_by_id;
});

3. 确认Policy注册正确性

检查AuthServiceProvider中的$policies数组,确保Termin::class和TerminPolicy::class的映射没有拼写错误,且命名空间正确。

4. 优化Controller授权调用

使用Laravel隐式模型绑定简化代码,同时避免手动查找模型的潜在问题:

public function edit(Termin $termin)
{
    $this->authorize('edit', $termin);

    // Rest of code...
}

5. 验证用户认证状态

确保访问编辑页面的用户已正确登录,Auth::user()能返回当前登录用户(未登录用户会被直接跳转至登录页,此问题概率较低)。


内容的提问来源于stack exchange,提问作者Andi Gashi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 15:45:41