I have made a Laravel 8 application (link to GitHub repo) that requires user registration and login.
I am currently working on adding user roles and permissions. I have 3 roles (types of users): Admin, Author, and Member. Each type of user should have access to a section of the dashboard.
The users table:
The roles table:
In routesweb.php
I have:
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']); });
In the User model (appModelsUser.php
) I have:
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('AppUser'); } 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; } }
In the AuthorController (ControllersDashboardAuthorController.php)
class AuthorController extends Controller { public function __construct() { $this->middleware('auth'); $this->middleware('role:ROLE_Author'); } public function index() { return view('dasboard.author'); } }
As the CheckRole middleware shows, if the user is not authorised, the message should be “This action is unauthorized”:
class CheckRole { /** * Handle an incoming request. * * @param IlluminateHttpRequest $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); } }
The problem
For a reason I have not been able to find out, trying to redirect an author to it’s section of the admin panel results in a 403 error:
User does not have any of the necessary access rights.
Question
What am I doing wrong?
Advertisement
Answer
After Reviewing your code .I have found few mistakes
1.In AuthorController you have passed role as ROLE_Author
instead of Author
$this->middleware('role:ROLE_Author');
But in db you have named role name as Author
so it should be
$this->middleware('role:Author');
2.In User model you have hasRole($role)
method but it is accessing role relationship
which has belongsToMany
relationship
public function roles() { return $this->belongsToMany(Role::class); }
So if you check db role_user
has empty record.So add related data in role_user
table but now you are adding role in users
table.
Suppose if you are looking for assigning role
in user table
then change relation role in User table
public function roles() { return $this->belongsTo(Role::class,'role_id','id'); }
if user has no access rights then it throws below error otherwise it goes to dashboard.
401 UNAUTHORIZED
Also in MemberController
you have to change middleware from
$this->middleware('role:ROLE_Member');
to
$this->middleware('role:Member');
Also in AuthorController
.you have error in blade file name. view('dasboard.author')
but if you see view folder
then you have named folder as dashboard
but in view you have mentioned dasboard.author
So change from this
public function index() { return view('dasboard.author'); }
to
public function index() { return view('dashboard.author'); }
Note: After reviewing I didn’t found mentioned error message “User does not have any of the necessary access rights.” in git repo.Also it doesnt throw 403 error for unauthorized users. So try to clear view cache ,browser cache.