I have a role middleware that passes a parameter to the middleware.
public function __construct(UserInterface $user, RoleInterface $role, MaritalStatusInterface $maritalStatus, CityInterface $city){
$this->middleware('auth');
//$this->middleware('role:System Admin'); I changed it to 6 for the id.
$this->middleware('role:6');
}
My RoleMiddleware is this
public function handle($request, Closure $next, ...$params)
{
$roles = $request->user()->roles()->get();
$roles = $roles->map(function($item){
return $item->id;
});
foreach ($params as $value) {
if( ! in_array($value, $roles->toArray())){
return redirect()->action('NavController#home');
}
}
return $next($request);
}
As you can see I it is very tied to 6. What if I want to add 7... I want to make it dynamically. My tables are Users Role_User and Roles. What table do I need and how to execute it.
since you want it dynamically you should have a database for the allowed roles .. then in the same controller you should do
$allowedRoles = AllowedRoles::all();
$loop=1;
foreach($allowedRoles as $role)
{
$roleString = $loop == 1 ? $role->value : $roleString.'|'.$role->value;
// where value is equivalent to the role of your role id in role database
$loop++;
}
$this->middleware('role:'.$roleString);
then in your middleware you should explode the roleString
public function handle($request, Closure $next, $roles)
{
$roles = explode('|',$roles);
$user = User::find($request->user()->id);
foreach($user->intRoles as $myRole)
{
if(in_array($myRole->role_id, $roles))
{
return $next($request);
}
}
// Redirect
return redirect()->back();
}
Related
I am new on laravel. I am actually having a problem with my middleware. I already registered it on Kernel.php file.
public function handle($request, Closure $next){
$user = Auth::user();
if($user->hasAnyRole('school'))
{
return $next($request);
}
return redirect('login');
}
here is my User model
public function roles(){
return $this->belongsToMany('App\Role');
}
public function hasAnyRoles(){
return null !== $this->roles()->whereIn('name', $roles)->first();
}
public function hasAnyRole(){
return null !== $this->roles()->where('name', $role)->first();
}
Try flipping the logic and also checking if logged in.
Do a (Auth::check() :
public function handle($request, Closure $next){
if (Auth::check()) {
$user = Auth::user();
if($user->hasAnyRole('school'))
{
return $next($request);
}
} else {
return redirect('login');
}
}
I have middleware UKM I want if the Auth::id() in the table ukm, hen can access the next request. But not working, if Auth::id() no in the table user can access.
public function handle($request, Closure $next)
{
$query = DB::table('ukm')->where('id_user',Auth::id())->get();
foreach($query as $key){
$cek = $key->id_user;
}
if ($cek != NULL) {
return $next($request);
}
return redirect('/');
}
try this...
public function handle($request, Closure $next)
{
$query = DB::table('ukm')->where('id_user',Auth::id())->first();
if ($query != NULL) {
return $next($request);
}
return redirect('/');
}
how about this ....
public function handle($request, Closure $next)
{
$query = DB::table('ukm')->pluck('id_user')->toArray();
if(in_array( Auth::user()->id, $query )
{
return $next($request);
}
return redirect('/');
}
I'am using Sentinel package, for example I've created middleware PCMiddleware
public function handle($request, Closure $next)
{
$roles = array_slice(func_get_args(), 2);
foreach ($roles as $role) {
if(Sentinel::check() && Sentinel::getUser()->inRole($role)){
return $next($request);
} else {
return redirect()->route('admin.errors');
}
}
}
Route:
$route->get('dashboard', ['as' => 'dashboard', 'uses' => 'AdminController#dashboard'])->middleware('role_check:member,hrd,super-admin');
and I've created user too with role hrd, which is any user with hrd role can access dashboard but when I loggedin endup with 404 how can I be able to access /dashboard even though I only have hrd role ?
maybe like this if user has any of these 3 role then he can access the route,
In Laravel already there is a way of transferring parameters for the middlewares. You can read about it here
public function handle($request, Closure $next)
{
$roles = array_slice(func_get_args(), 2);
$status = false;
foreach ($roles as $role) {
if(Sentinel::check() && Sentinel::getUser()->inRole($role)){
$status = true;
break;
}
}
if ($status) {
return $next($request);
}
return redirect()->route('admin.errors');
}
In this example, your code will work if at least one of the passed parameters exists
I have two levels in middleware and it does not work well, then how to write middleware in two levels at once?
public function __construct()
{
$this->middleware('auth');
$this->middleware('Admin');
$this->middleware('Teacher');
}
I also have this, i want to check that this page is only accessible by admin and teacher, but in writing the code it does not work well and how to write it right?
#if (Auth::check() && Auth::user()->level == 'Admin')
#elseif (Auth::check() && Auth::user()->level == 'Teacher')
#endif
If you can help me in solving this problem i am very grateful
in my experience i did that using a middleware ..
Middleware
public function handle($request, Closure $next, $roles)
{
$roles = explode('|',$roles);
$user = User::find($request->user()->id);
foreach($user->intRoles as $myRole)
{
if(in_array($myRole->role_id, $roles))
{
return $next($request);
}
}
return redirect()->back();
}
Route
Route::group( ['middleware' => 'rolePermissions:1|2|3'], function(){
Route::get('/users',['as'=>'users', 'uses'=>'PagesController#users']);
});
mydomain.com/users will only be accessible for those users who have roles (id) of 1, 2, or 3 ..
You have 2 separate middleware for checking user level. This forces both the conditions and doesn't work the way you want. You need a single middleware to check the user level and pass parameters to it.
Assume we have this middleware named as access.
public function handle($request, Closure $next, $levels)
{
$userLevels = explode(',', $levels);
if (Auth::check() && in_array(Auth::user()->level, $userLevels)) {
return $next($request);
}
return redirect('/home');
}
In your controller add this
public function __construct()
{
$this->middleware(['auth', 'access:Admin,Student']);
}
I have 2 Middlewares.
My StaffMiddleware
public function handle($request, Closure $next)
{
if( $request->user()->role->name != 'staff'){
return redirect()->route('store');
}
return $next($request);
}
My AdminMiddleware
public function handle($request, Closure $next)
{
if( $request->user()->role->name != 'admin'){
return redirect()->route('store');
}
return $next($request);
}
The Problem is my UnitController
public function __construct(UnitInterface $unit){
$this->middleware('staff');
$this->middleware('admin);
$this->unit = $unit;
}
It should work either the role is a staff or an admin. Do I need to create another Middleware to combine them both?
This completely depends on the way your Middleware is designed. As you can see from your code, it simple redirects if the role is not staff or not admin so there would be no way for you to have an OR logic.
However, you could use middleware parameters to avoid this.
$this->middleware('role:admin,staff');
This will use the role middleware and pass admin and staff as parameters.
Then you can use these parameters in your middleware:
public function handle($request, Closure $next, ...$params)
{
if(!in_array($request->user()->role->name, $params)){
return redirect()->route('store');
}
return $next($request);
}
This captures the additional parameters into an array $params in which you can check if the user's role matches one of the parameters.
**try this**
public function __construct(UnitInterface $unit){
$this->middleware(function ($request, $next) {
if($request->user()->role->name == 'staff' || $request->user()->role->name == 'admin')
{
return $next($request);
}
return redirect()->route('store')
});
}
No middleware