Why does middleware always fires? - laravel

After logging in, my app always goes to the dashboard as intended.
But even after clicking other directories, it always goes to the dashboard.
As I find out, the middleware named RedirectIfAdmin always fires.
I am using hesto/multi-auth.
RedirectIfAdmin:
public function handle($request, Closure $next, $guard = 'admin')
{
if (Auth::guard($guard)->check()) {
return redirect('myapp/dashboard');
}
return $next($request);
}
On my admin route file:
Route::group(['prefix' => '/myapp', 'as'=>'myapp.'], function () {
Route::resources([
'user' => '\App\Http\Controllers\UserController'
]);
});
So if I go to myapp/user/ i am always redirected to myapp/dashboard.
I know that it was the code insde the RedirectIfAdmin that is firing when I go to myapp/user because if I change it to myapp/dashboard123 then it goes to that url everytime i browse myapp/user, myapp/user/create, myapp/user/123, myapp/user/123/edit, etc.
Any thoughts?

While calling your myapp/user/ try to call it with
project-url/admin/myapp/user
if you are calling with route then use like
admin.myapp.user
Step 1:
Inside your RouteServiceProvider.php
In that inside map function add this line:
$this->mapWebRoutes();
$this->mapAdminRoutes();
Step 2:
Inside RouteServiceProvider class add this function:
protected function mapAdminRoutes()
{
Route::group([
'middleware' => ['web', 'admin', 'auth:admin'],
'prefix' => 'admin',
'as' => 'admin.',
'namespace' => $this->namespace,
], function ($router) {
require base_path('routes/admin.php');
});
}
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
Step 3:
Run below command in your project
php artisan optimize:clear

Check the __construct() on the user controller see if you referenced it there

Related

How can I add OR relationship in laravel middleware for a Route

I'm using spatie/laravel-permission to add permissions for my routes.
One of the routes I have can be accessed by two permissions (earnings, financial_fund). The user doesn't need to have both permissions to access the controller. He can access the controller by having one of the permissions or both of them.
I've tried to write something like this.
Route::group(['middleware' => ['can:earnings']], function () {
Route::get('/payment', [PaymentsController::class, 'getAll']);
Route::post('/payment/cash', [PaymentsController::class, 'addCashPayment']);
});
Route::group(['middleware' => ['can:financial_fund']], function () {
Route::get('/payment', [PaymentsController::class, 'getAll']);
Route::post('/payment/cash', [PaymentsController::class, 'addCashPayment']);
});
But the above code allows only users with can:earnings permission to access the routes, it doesn't allow users with can:financial_fund permission.
I've also tried to write something like this
Route::group(['middleware' => ['can:earnings,financial_fund']], function () {
Route::get('/payment', [PaymentsController::class, 'getAll']);
Route::post('/payment/cash', [PaymentsController::class, 'addCashPayment']);
});
But this requires both of permissions to exist with the current user.
How can I tell that I want only one of the permissions at least to exist?
I have found that Laravel has introduced the canAny for use in blade templates. Is there a way I can use it in my api.php file while defining the Routes?
I fixed it by creating a new middleware
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class AuthorizeCanAny
{
public function handle(Request $request, Closure $next, ...$permissions)
{
if (!$request->user()) {
abort(403);
}
$userPermissions = array_map(function ($e) {
return $e['name'];
}, $request->user()->permissions->toArray());
$userPermissionsIntersect = array_intersect($userPermissions, $permissions);
if (!sizeof($userPermissionsIntersect)) {
abort(403);
}
return $next($request);
}
}
Adding the middleware to kernal.php file
protected $routeMiddleware = [
...,
'canAny' => AuthorizeCanAny::class,
];
Then use it in the router
Route::group(['middleware' => ['canAny:earnings,financial_fund']], function () {
Route::get('/payment', [PaymentsController::class, 'getAll']);
Route::post('/payment/cash', [PaymentsController::class, 'addCashPayment']);
});

Laravel Protected Route With same Model

I changed the users table and put a field called "role" and was wondering if it is possible to use middleware to protect routes only by checking this field.
The table users:
I wnated something like this:
If user role == 0
Route::group(['middleware' => 'auth'], function () {});
If user role == 1
Route::group(['middleware' => 'auth:customers'], function () {});
However with the same table
Make a new middleware:
php artisan make:middleware CustomerMiddleware
The function handle in the new middleware:
public function handle($request, Closure $next)
{
if(Auth::check()){
if($request->user()->role != 0){
return redirect('/');
}
}
return $next($request);
}
The protected route in app/Http/Kernel.php
'CustomerMiddleware' => \App\Http\Middleware\CustomerMiddleware::class,
The group routes:
Route::group(['middleware' => 'CustomerMiddleware'], function () { });

Laravel middleware multi roles routing

I have problem to make routing with middleware multi roles
I have tried some in internet but still wont work
I have 3 roles, superadmin, admin and member
I want the superadmin and admin can access the add page
here is my code :
Route::group(['prefix' => 'staff', 'middleware' => 'auth'], function () {
Route::GET('/add', [
'uses' => 'StaffController#page_add',
'middleware' => 'rule:superadmin', ???
]);
});
I have tried to put 'middleware' => 'rule:superadmin|rule:admin'
but wont work
thank you
Create a middleware file eg Role.php
public function handle($request, Closure $next, ... $roles)
{
if (!Auth::check()) // I included this check because you have it, but it really should be part of your 'auth' middleware, most likely added as part of a route group.
return redirect('login');
$user = Auth::user();
if($user->isAdmin())
return $next($request);
foreach($roles as $role) {
// Check if user has the role This check will depend on how your roles are set up
if($user->hasRole($role))
return $next($request);
}
return redirect('login');
}
Finally in your web routes
Route::get('admin/scholen/overzicht', 'SchoolsController#overview')->middleware('role:editor,approver');
Route::get('admin/scholen/{id}/bewerken', 'SchoolsController#edit')->middleware('role:admin');
Check out this best answer for more details
Hey you can put a column named "role" in your users table then check it with a condition.
Route::get('/add', function() {
if (Auth::user()->role == 'superadmin' || Auth::user()->role == 'admin') {
return view('add-page');
}
else {
return view('error-page');
}
});

Laravel login redirected you too many times

I have been struggling with this from quiet a time now, what i am trying is to redirect all the url's hit by non-logged in users to login page and it gives me this error, which I am sure is because it is creating a loop on /login URL. authentication is checking for authorized user in login page also. however I wish the login page should be an exception when checking the auth. I may be doing something wrong which I am not able to get. here goes my code.
routes.php
Route::post('login', 'Auth\AuthController#login');
Route::get('login' , 'Auth\AuthController#showLoginForm');
Route::get('/' , 'Auth\AuthController#showLoginForm');
kernel.php
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'can' => \Illuminate\Foundation\Auth\Access\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'acl' => \App\Http\Middleware\CheckPermission::class,
];
Authenticate class
class Authenticate
{
public function handle($request, Closure $next, $guard = null) {
if (Auth::guard($guard)->guest()) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('login');
}
}
return $next($request);
}
}
AuthController class
class AuthController extends Controller {
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
protected $redirectTo = '/dashboard';
protected $loginPath = '/login';
protected $redirectPath = '/dashboard';
public function __construct(){
$this->middleware('auth', ['except' =>'login']);
/* I have been trying these many things to fix this, all in loss.
// $this->middleware('acl'); // To all methods
// $this->middleware('acl', ['only' => ['create', 'update']]);
// $this->middleware('guest', ['only' => ['/login']]);
// echo "Message"; exit;
// $this->middleware('auth');
// $this->middleware('auth', ['only' => ['login']]);
// $this->middleware('auth', ['only' => ['/login']]);
// $this->middleware('auth', ['except' => 'login']);
// $this->middleware('guest');
// $this->middleware('guest', ['only' => ['logout' , 'login', '/login', '/']]);
}
Please help me, It going all above my head, seems some sort of rocket science to me. well btw I am new to laravel and may be doing some silly thing around, apologies for that. Thanks in Advance.
You need add route login outside Laravel group:
routes.php
Route::auth();
Route::group(['middleware' => 'auth'], function () {
// All route your need authenticated
});
Aditionally, you can see yours route list using:
php artisan route:list
Why you are doing all this just to redirect every non-logged in user to login form?
i think you can just do this
Routes.php
Route::post('login', 'Auth\AuthController#login');
Route::get('login' , 'Auth\AuthController#showLoginForm');
Route::get('/' , 'Auth\AuthController#showLoginForm');
Route::group(['middleware' => 'auth'], function () {
// any route here will only be accessible for logged in users
});
and auth controller construct should be like this
AuthController
public function __construct()
{
$this->middleware('guest', ['except' => 'logout']);
}
The problem is with your routes.
When I enter and I am not logged out you send me to login(get) route. And as you are specifying the middleware in the construct function in the AuthController, every time a method of the AuthController is called, construct function is called again and sends you back at login.. and it repeats indefinitely.
like #mkmnstr say
The problem is with your routes.
When I enter and I am not logged out you send me to login(get) route. And as you are specifying the middleware in the construct function in the AuthController, every time a method of the AuthController is called, construct function is called again and sends you back at login.. and it repeats indefinitely.
to fix that u should add
Auth::logout();
Here
...
} else {
Auth::logout(); // user must logout before redirect them
return redirect()->guest('login');
}
...
If your working with custom middleware you must follow it's all rules
in my case, I have to define a custom route class in the web middleware group.
In the world of copy-paste sometime we make mistakes.
Middleware :
public function handle($request, Closure $next)
{
if(!isset(session('user'))){
return redirect('login');
}
return $next($request);
}
}
My Mistake in Kernel.php
if custom middleware class present in web $middlewareGroups will check condition 2 times so it will give error as: redirected you too many times
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\webUser::class, //Remove
],
protected $routeMiddleware = [
'webUser'=> \App\Http\Middleware\webUser::class //Keepit
]
I had same problem after creating my own route service provider. The problem was that when I tried to login, in first time login page showed and after entering credentials I encountered "redirected too many times" and redirected to my admin dashboard and login route!
the solution was: adding middleware "web" into my routes:
Route::middleware('web')->group(base_path('Admin/routes.php'));

NotFoundExeception in RouteCollection when using multiple route groups

I define in RouteServiceProvider.php this map implementation:
public function map(Router $router, Request $request)
{
$locale = $request->segment(1);
$this->app->setLocale($locale);
$router->group(['prefix' => '{lang}'], function($router) {
require app_path('Http/routes.php');
});
}
In app/routes.php Ι also define a route group
Route::group(['prefix' => 'admin', 'middleware' => 'auth'], function (){
//code
);
Now when Ι try to access to admin/xxx it show me this exception
NotFoundHttpException in RouteCollection.php line 161:
I try to put the definition of the first route group in routes.php but that didn't work.
How can Ι solve the problem?
The group who defined into the RouteServiceProvider.php comes before the group who defined into the routes.php
So, you should access your route like this:
xxx/admin

Resources