Hello i have try to do permisssion and role in laravel 9 but i have a error . User model
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable implements MustVerifyEmail
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
'secretword',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function roles()
{
return $this
->belongsToMany('App\Role')
->withTimestamps();
}
public function users()
{
return $this
->belongsToMany('App\User')
->withTimestamps();
}
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;
}
};
Role model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
use HasFactory;
}
AdminController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AdminController extends Controller
{
public function __construct()
{
$this->middleware('auth');
$this->middleware('role:ROLE_ADMIN');
}
public function index()
{
return view('admin.home');
}
}
SuperAdminController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class SuperAdminController extends Controller
{
public function __construct()
{
$this->middleware('auth');
$this->middleware('role:ROLE_SUPERADMIN');
}
public function index()
{
return view('superadmin.home');
}
}
web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('auth/login');
});
Auth::routes(['verify' => true]);
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::get('/admin', [App\Http\Controllers\AdminController::class, 'index']);
Route::get('/superadmin', [App\Http\Controllers\SuperAdminController::class, 'index']);
Route::resource('posts', PostController::class);
app / Http / Middleware / CheckRole.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class CheckRole
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
if (! $request->user()->hasRole($role)) {
abort(401, 'This action is unauthorized.');
}
return $next($request);
}
}
I try to do permissions and roles in laravel 9.And when i want to go /admin i have this error and show me this file i want to know how can i resolve this error for all good work?
CodePudding user response:
You need pass and accept the parameter of role, in middleware.
Your middleware
public function handle(Request $request, Closure $next, string $role)
If you are using route for middleware then
Route::resource(...)->middleware('middlewareName:roleName');
If controller being used
$this->middleware(\App\Http\Middleware\CheckRole::class.':roleName')
To send argument to the middleware, use :
after the middleware name. To send multiple argument, separate the arguments with ,
.
CodePudding user response:
I strongly recommend using Policy classes for this. Then you can simply use the can
middleware.
More info here: https://laravel.com/docs/9.x/authorization#creating-policies
Your models basically would have their own policy classes per model, then you can fine tune exactly what users can do based on what their role is.
No need to reinvent the wheel here.