【问题标题】:What causes the user access error in this Laravel 8 application?是什么导致此 Laravel 8 应用程序中的用户访问错误?
【发布时间】:2021-06-19 10:34:42
【问题描述】:

我制作了一个 Laravel 8 application(链接到 GitHub 存储库),需要用户注册和登录。

我目前正在添加用户角色和权限。我有 3 个角色(用户类型):管理员、作者和成员。每种类型的用户都应该有权访问仪表板的某个部分。

用户表:

角色表:

routes\web.php 我有:

Route::get('/', [HomepageController::class, 'index'])->name('homepage');

Auth::routes();

Route::group(['middleware' => ['auth']], function() {
    Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
    Route::get('/dashboard/profile', [UserProfileController::class, 'index'])->name('profile');
    Route::match(['get', 'post'],'/dashboard/profile/update', [UserProfileController::class, 'update'])->name('profile.update');
    Route::post('/dashboard/profile/deleteavatar/{id}/{fileName}', [UserProfileController::class, 'deleteavatar'])->name('profile.deleteavatar');

    //User roles
    Route::get('/dashboard/author', [AuthorController::class, 'index']);
});

User 模型中 (app\Models\User.php) 我有:

class User extends Authenticatable
{
    use HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'role_id',
        'username',
        'first_name',
        'last_name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function roles() {
      return $this->belongsToMany(Role::class);
    }

    public function users()
    {
        return $this
            ->belongsToMany('App\User');
    }

    public function authorizeRoles($roles)
    {
      if ($this->hasAnyRole($roles)) {
        return true;
      }
      abort(401, 'This action is unauthorized.');
    }

    public function hasAnyRole($roles)
    {
      if (is_array($roles)) {
        foreach ($roles as $role) {
          if ($this->hasRole($role)) {
            return true;
          }
        }
      } else {
        if ($this->hasRole($roles)) {
          return true;
        }
      }
      return false;
    }

    public function hasRole($role)
    {
      if ($this->roles()->where('name', $role)->first()) {
        return true;
      }
      return false;
    }
}

AuthorController(Controllers\Dashboard\AuthorController.php)中

class AuthorController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
        $this->middleware('role:ROLE_Author');
    }

    public function index()
    {
        return view('dasboard.author');
    }
}

正如 CheckRole 中间件所示,如果用户未授权,则消息应为“此操作未授权”:

class CheckRole
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next, $role)
    {
        if (!$request->user()->hasRole($role)) {
            abort(401, 'This action is unauthorized.');
        }
        return $next($request);
    }
}

问题

由于我无法找到的原因,尝试将 作者 重定向到它的管理面板部分会导致 403 错误

User does not have any of the necessary access rights.

问题

我做错了什么?

【问题讨论】:

  • 能否请您展示带有角色的表格?
  • @Dmitry 我不想使用任何包。
  • @RazvanZamfir 你能把更新的代码添加到 github repo 和 sql 文件的数据吗
  • @JohnLobo 在 repo 的 user_roles 分支上,有所有最新的代码和 sql 导出。

标签: php laravel


【解决方案1】:

由于 laravel 7 你有方法id(),所以你不必使用$table->increments('id');(它导致我的外键约束错误)。

【讨论】:

    【解决方案2】:

    您的权限表和 role_has_permissions 表在哪里。您只保存角色,但您没有授予任何角色权限。所以它会给你 403 错误。

    使用此示例:- https://spatie.be/docs/laravel-permission/v4/introduction

    【讨论】:

      【解决方案3】:

      查看您的代码后,我发现了一些错误

      1.在 AuthorController 中,您将角色传递为 ROLE_Author 而不是 Author

       $this->middleware('role:ROLE_Author');
      

      但在 db 中,您已将角色名称命名为 Author,所以它应该是

      $this->middleware('role:Author');
      

      2.在用户模型中,您有hasRole($role) 方法,但它正在访问具有belongsToMany 关系的role relationship

       public function roles() {
      
        return $this->belongsToMany(Role::class);
      }
      

      所以如果你检查 db role_user 有空记录。所以在role_user 表中添加相关数据,但现在你在users 表中添加角色。

      假设如果您要在user table 中分配role,然后在User table 中更改关系角色

       public function roles() {
            return $this->belongsTo(Role::class,'role_id','id');
          }
      

      如果用户没有访问权限,则会抛出以下错误,否则会转到仪表板。

      401 UNAUTHORIZED
      

      同样在MemberController 中,您必须更改中间件

        $this->middleware('role:ROLE_Member');
      

        $this->middleware('role:Member');
      

      同样在AuthorController.你有刀片文件名错误。 view('dasboard.author') 但如果您看到 view folder 则您已将文件夹命名为 dashboard 但鉴于您提到了 dasboard.author 所以从这里改变

       public function index()
       {
          return view('dasboard.author');
       }
      

       public function index()
       {
          return view('dashboard.author');
       }
      

      注意:在查看后,我没有发现提到的错误消息“用户没有任何必要的访问权限。”在 git repo.Also 它不会为未经授权的用户抛出 403 错误。所以尝试清除视图缓存,浏览器缓存。

      【讨论】:

      • 它不起作用。我收到View [.dasboard.author] not found. 错误。 `
      • @RazvanZamfir 。是的,你有拼写错误,所以它应该是 public function index() { return view('dashboard.author'); } 。检查我的更新答案
      • 我仍然看到 User does not have any of the necessary access rights 而不是 This action is unauthorized
      • 我已经检查了您的项目。您没有任何此类错误代码消息。但请确保您具有与您在分支github.com/Ajax30/Larablog/tree/user_roles 中提供的代码库相同的代码库
      • 我已经验证了整个代码库。没有这样的消息。如果是这样,那么一旦你验证你是否提供了相同的代码库。如果是这样,你尝试了哪个用户,所以我可以尝试相同的用户
      【解决方案4】:

      您没有正确获得角色的主要问题是根据此进行一些更改:

      在作者控制器处

      1- 更新$this->middleware('role:ROLE_Author'); => $this->middleware('role:Author');

      2- 更新return view('dasboard.author'); => return view('dashboard.author');

      在榜样方面

      1- 添加public $timestamps = false;

      2- 添加 public function users() { return $this->hasMany(User::class); }

      在用户模型中

      1- 更新

      public function roles() { return $this->belongsToMany(Role::class); }

      To be:
      

      public function role() { return $this->belongsTo('App\Models\Role'); }

      2- $this->roles()->where('name', $role)->first() => $this->join('roles', 'users.role_id', 'roles.id')->where('roles.name', $role)->first()

      在创建用户迁移时

      1- 删除$table->foreignId('role_id')->constrained('roles'); 2-添加 $table->unsignedInteger('role_id')->nullable(); $table->foreign('role_id')->references('id')->on('roles');

      (Note: If your application is on production then you need to create another migration to add the new field instead of add the field to old migration)
      

      【讨论】:

        猜你喜欢
        • 2021-08-25
        • 1970-01-01
        • 2021-01-12
        • 2022-07-06
        • 1970-01-01
        • 2016-10-26
        • 1970-01-01
        • 2021-08-18
        • 2012-05-05
        相关资源
        最近更新 更多