Same route different middleware route group - laravel

Here is my super admin middleware,
if(Auth::user()->role_id == 1) {
return $next($request);
}
return redirect('/');
and,here is admin middleware,
if(Auth::user()->role_id == 2) {
return $next($request);
}
return redirect('/');
Here is my manager middleware,
if(Auth::user()->role_id == 3) {
return $next($request);
}
return redirect('/');
Here is my seller middleware,
if(Auth::user()->role_id == 4) {
return $next($request);
}
return redirect('/');
and, this is web.php,
Route::middleware(['superadmin'])->group(function () {
Route::resource('users', UserController::class);
//and more
});
Route::middleware(['admin'])->group(function () {
Route::resource('users', UserController::class);
//and more
});
Route::middleware(['manager'])->group(function () {
Route::resource('managers', ManagerController::class);
//and more
});
Route::middleware(['seller'])->group(function () {
Route::resource('sellers', SellersController::class);
//and more
});
I have 4types of middleware. Each route group have different route. Its working properly. Some of the routes are also used in another group. But then it doesn't work.

Doesn't make sense to have two different middleware here. What do you want to achieve? If the user is an admin then what and if user is a superadmin then what?
If the purpose is to just allow either admin or superadmin to access routes defined under the middleware group then a single middleware is enough.
//IsAdmin middleware
//if the user is either superadmin or admin allow else redirect
if(in_array(Auth::user()->role_id, [1,2])) {
//If you want to process based on whether admin or superadmin
//you can do it here
//if(Auth::user()->role_id ===1) {
// process when user is superadmin
// }
//else {
// process when user is admin
//}
return $next($request);
}
return redirect('/');
Then protect the routes in routes file
Route::middleware(['isAdmin'])->group(function () {
Route::resource('users', UserController::class);
});

Related

Protecting Routes With Two middle-wares So that both users can access it

I am trying to protect a route using two middle-wares so that both expert and user can access the same route but as soon a user tries to access the route he is logged out.
I had created two middle-wares for expert and user and protect the route using these middle-wares.
Web.php
Route::group(['middleware' => ['expert','user']], function () {
Route::post('/showForm','UserController#showFormFilled');
});
User Middle ware
public function handle($request, Closure $next)
{
//////////////////// check if user is logged in ///////////////////
if(Auth::check())
{
////////////////// check user role id //////////////////////////
if(auth()->user()->role_id == 3)
{
return $next($request);
}
else if (auth()->user()->role_id==2)
{
return redirect('/expert');
}
}
else
{
return redirect('/login');
}
}
Expert Middle ware
public function handle($request, Closure $next)
{
if(Auth::check()){
if(auth()->user()->role_id == 2)
return $next($request);
else if (auth()->user()->role_id==3)
return redirect('/dashboard');
}
else {
return redirect('/login');
}
}
Both the users should be able to access the same route.
#hamzahummam - there is no way to achieve what you are looking for using the above separate-middlware-for-each-type method. Each middleware prematurely redirects [either to /dashboard or to /expert etc] the request without allowing it to passthrough other middleware. Best would be to use a third-party package that provides a more comprehensive and fine-grained access control [example: https://github.com/Zizaco/entrust]
If that's not an option, the best case would be to implement a single middleware and pass the role as parameter. See: Laravel Middleware Parameters
A minimal example would look like:
public function handle($request, Closure $next, $role)
{
// Assuming Auth::check() passes
$roleId = auth()->user()->role_id;
if ($roleId == 2 && strpos($role, 'expert') !== false) {
// Logged in user is `expert` and route allows `expert` access
return $next($request);
} else if ($roleId == 3 && strpos($role, 'user') !== false) {
// Logged in user is `user` and route allows `user` access
return $next($request);
} // and so on...
// Handle failures here
if ($roleId == 2 && strpos($role, 'expert') === false) {
// an `expert` is trying to access route that can't be accessed
return redirect('/expert-dashboard');
} // and so on...
}
You'd define routes as:
Route::group(['middleware' => ['new_middleware:expert,user' ]], function () {
Route::post('/showForm','UserController#showFormFilled');
});
Hope this helps.

How to protect a route with middleware in laravel?

i have a problem with my middleware. when i login as admin, it's working fine and redirect to /Admin/home same as Operator (i have 2 user, Admin & Operator). The problem is when i hit url as example : /Operator/home as Admin role, it can access it. And that's the problem.
I'have create a new middleware CheckMiddleware, and registered to kernel in array $routeMiddleware as checkMiddleware:
public function handle($request, Closure $next)
{
$user = $request->user();
if ($user) {
if ($user->isAdmin()) {
return $next($request);
}elseif($user->isOperator()){
return $next($request);
}
}
return dd('Forbidden page. you have to login as admin/operator');
}
In the route :
Route::group(['prefix'=>'Admin' ,'middleware' => 'checkMiddleware'], function() {
Route::get('/home', 'HomeController#index')->name('homeAdmin');
});
Route::group(['prefix'=>'Operator' ,'middleware' => 'checkMiddleware'], function() {
Route::get('/home', 'HomeController#index')->name('homeAdmin');
});
Auth::routes();
in User model :
public function isAdmin(){
if ($this->role_id === 1) {
return true;
}
return false;
}
public function isOperator(){
if ($this->role_id === 2) {
return true;
}
return false;
}
What i want is, Admin cannot access Operator and Operator Cannot Access Admin.
if this is not clear, tell me what file you want to see.
The problem is if user is admin then accept request and user is operator still accept request. That code below
if ($user->isAdmin()) {
return $next($request);
}elseif($user->isOperator()){
return $next($request);
}
For simple solution, just create two middleware for admin and operator. Then apply admin middleware for route (group) need admin role, and apply operator middleware for route (group) need operator role.
If you have some route allow admin and operator role access, just add both to that route.
UPDATE
If you want to use 1 middleware, do like this :
if ($user->isAdmin() && $request->route()->getPrefix() == 'admin') {
return $next($request);
}
if ($user->isOperator() && $request->route()->getPrefix() == 'operator') {
return $next($request);
}
return abort(401) // OR SOME ROUTE YOU WANT

err_too_many_redirects and This page isn’t working in laravel my middleware

i have two users who i have two role normal user and debtor user. i want what to prevent the debtor user from accessing normal user dashboard . i have created debtors dashboard too.below is what i have tried.how can i archive this.
this is my web.php
////// User debtors Authentications ///////////
Route::middleware(['debtors'])->group(function(){//debtors routes will goes here
Route::get('/debtors/home', 'HomeController#kfsdebtors_form');
Route::get('/debtors/kfsdebtors_form', 'HomeController#defaultersdashboard');
Route::get('/debtors/applications_dashboard', 'HomeController#applications_dashboard');
Route::get('/debtors/manage_debt', 'HomeController#manage_debt');
Route::post('/debtors/manage_debt', 'HomeController#transaction');
Route::get('/debtors/manage_debt', 'HomeController#defaulters');
Route::get('/debtors/view_transaction', 'HomeController#view_transaction');
Route::post('/debtors/view_transaction', 'HomeController#view_transaction');
// Route::get('/user/{data}', 'UserController#getData');
// Route::post('/user/{data}', 'UserController#postData');
});
// Route::group(['middleware' => 'debtors'], function () {
// Route::get('/debtors/home/kfsdebtors_form', 'HomeController#kfsdebtors_form');
// Route::get('/debtors/applications_dashboard', 'HomeController#applications_dashboard');
// Route::get('/debtors/manage_debt', 'HomeController#manage_debt');
// });
////// User normal user Authentications ///////////
Route::middleware(['normal_user'])->group(function(){
Route::get('/home', 'HomeController#index');
Route::get('/home', 'HomeController#balance');
});
// Route::group(['middleware' => 'is.admin'], function () {
// Route::get('/user/{data}', 'UserController#getData');
// Route::post('/user/{data}', 'UserController#postData');
// });
Route::get('/register_sawmill', 'Auth\register_sawmill#create')->name('register_sawmill');
Route::post('/register_sawmill', 'Auth\register_sawmill#register');
Route::get('logout', 'Auth\LoginController#logout', function () {
this is my middleware for debtors.php
public function handle($request, Closure $next)
{
if (Auth::user()->debtor == 1)
{
return $next($request);
}
return redirect()->guest('/debtors/home');
}
}
this is normal_user.php middleware
public function handle($request, Closure $next)
{
// if(Auth::check()) {
// if(Auth::user()->debtor == 0) {
// return $next($request);
// }
// }
// return redirect('/home');
// if(!Auth::check() || Auth::user()->debtor != '0'){
// return redirect()->route('/debtors/home');
// }
// return $next($request);
if(Auth::check()) {
if(Auth::user()->debtor == 0) {
return $next($request);
}
}
return redirect('/debtor/home');
}
```
I think you should change return redirect('/home');
and redirect to a simple page, like return redirect('/register_sawmill');
the problem I think, is that the normal user middleware check if the user is authenticated, if not, it should redirect to some page that is not maintained by the middleware

How can i register multiple middleware permissions in routegroup?-Laravel

I have 3 roles roles, admin, tutor and student. i want to place them in 3 different goups, i however want the admin to be in all the groups. I have tried different methods to add the admin to other routes but it's not working. How can i make admin use all routes in tutor's middleware? Here is my code
AdminMiddleware, similar to all the others
class AdminMiddleware
{
public function handle($request, Closure $next)
{
if(Auth::check() && Auth::user()->isRole()=="admin") {
return $next($request);
}
return redirect('login');
}
}
routesmiddleware - in web.php
Route::group(['middleware'=>['auth'=>'admin']], function (){
//admin routes
}
Route::group(['middleware'=>['auth'=>'tutor']], function (){
//tutor routes
}
in the Kernel.php
'admin' => \App\Http\Middleware\AdminMiddleware::class,
'tutor' => \App\Http\Middleware\TutorMiddleware::class,
'student' => \App\Http\Middleware\StudentMiddleware::class,
in user model
public function isRole(){
return $this->role;
}
What you can do is define a middleware that takes the supported roles as argument:
class HasRoleMiddleware
{
public function handle($request, Closure $next, ...$roles)
{
if(Auth::check() && in_array(Auth::user()->getRole(), $roles)) {
return $next($request);
}
return redirect('login');
}
}
This middleware expects that User::getRole() returns the role as string, i.e. admin or tutor. Then you need to define the middleware in Kernel.php as you have already done:
'any_role' => \App\Http\Middleware\HasRoleMiddleware::class,
And finally you can use the middleware like this:
Route::group(['middleware' => 'auth'], function () {
Route::group(['middleware' => 'any_role:admin'], function () {
// admin routes
}
Route::group(['middleware' => 'any_role:admin,tutor'], function () {
// tutor routes
}
}
As you can see, I've also nested the route groups which perform role checks inside another route group which checks for authentication. This makes it more readable and reduces the risk you forget an authentication check in a future extension of your routes.

Request goes to each middleware laravel 5.2

I'm using laravel 5.2 with entrust/zizaco. When the user authenticates, they have the role admin, but when I put dd(1) in my app_user role middleware the request enters it !!
The request also enters admin, and business_owner role middlewares.
And even when the user logs out, after that each of their requests goes through auth middleware !!
Route::group(['middleware' => 'auth'], function () {
Route::group(['middleware' => ['role:admin']], function (){
// Routes go here
});
Route::group(['middleware' => ['role:app_user']], function (){
// Routes go here
});
Route::group(['middleware' => ['role:business_owner']], function (){
// Routes go here
});
});
Yes, request should enter in authenticate middleware and you can write your codes in middleware.
This is laravel built in middleware for authenticate users:
public function handle($request, Closure $next)
{
if ($this->auth->guest()) { // if user isn't authenticated
if ($request->ajax()) { // if request is ajax
return response('Unauthorized.', 401); // return 401 res
} else {
return redirect()->guest('login'); // else redirect login page
}
}
return $next($request); // return next res(e.g dashboard) if user is authenticated
}

Resources