Define the four routes with different middleware role wise.
Issue arrive is call DepartmentStaff Route every time.if i login Admin or Customer.
Call last written route every time.
//admin Route
Route::get('edit_profile', [UserController::class, 'edit_profile'])->name('edit_profile')->middleware(CheckAdminRole::class);
Route::post('profile_update', [UserController::class, 'profile_update'])->name('profile_update')->middleware(CheckAdminRole::class);
Route::get('change_password', [UserController::class, 'change_password'])->name('change_password')->middleware(CheckAdminRole::class);
Route::post('password_update', [UserController::class, 'password_update'])->name('password_update')->middleware(CheckAdminRole::class);
// Customer Route
Route::get('edit_profile', [UserController::class, 'edit_profile'])->name('edit_profile')->middleware(CheckCustomerRole::class);
Route::post('profile_update', [UserController::class, 'profile_update'])->name('profile_update')->middleware(CheckCustomerRole::class);
Route::get('change_password', [UserController::class, 'change_password'])->name('change_password')->middleware(CheckCustomerRole::class);
Route::post('password_update', [UserController::class, 'password_update'])->name('password_update')->middleware(CheckCustomerRole::class);
//DepartmentStaff Route
Route::get('edit_profile', [UserController::class, 'edit_profile'])->name('edit_profile')->middleware(CheckDepartmentStaffRole::class);
Route::post('profile_update', [UserController::class, 'profile_update'])->name('profile_update')->middleware(CheckDepartmentStaffRole::class);
Route::get('change_password', [UserController::class, 'change_password'])->name('change_password')->middleware(CheckDepartmentStaffRole::class);
Route::post('password_update', [UserController::class, 'password_update'])->name('password_update')->middleware(CheckDepartmentStaffRole::class);
//admin middleware
public function handle(Request $request, Closure $next)
{
if (auth()->user()->role == 1) {
return $next($request);
}
return redirect('error/404');
}
//customer middleware
public function handle(Request $request, Closure $next)
{
if (auth()->user()->role == 4) {
return $next($request);
}
return redirect('error/404');
}
//Department middleware
public function handle(Request $request, Closure $next)
{
if (auth()->user()->role == 2) {
return $next($request);
}
return redirect('error/404');
}
You can use only one middleware to check routes like:
//middleware
public function handle(Request $request, Closure $next)
{
if (in_array(auth()->user()->role, [1, 2, 3])) {
return $next($request);
}
return redirect('error/404');
}
And routes:
Route::get('edit_profile', [UserController::class, 'edit_profile'])->name('edit_profile')->middleware(CheckRole::class);
Route::post('profile_update', [UserController::class, 'profile_update'])->name('profile_update')->middleware(CheckRole::class);
Route::get('change_password', [UserController::class, 'change_password'])->name('change_password')->middleware(CheckRole::class);
Route::post('password_update', [UserController::class, 'password_update'])->name('password_update')->middleware(CheckRole::class);
Related
I'm using Laravel Breeze + Inertia (React) and want to implement custom auth.
I'm having infinite redirection (ERR_TOO_MANY_REDIRECTS) when visiting /dashboard on this middleware.
Route::get('register', [RegisteredUserController::class, 'create'])
->name('register');
Route::post('register', [RegisteredUserController::class, 'store']);
Route::get('login', [AuthenticatedSessionController::class, 'create'])
->name('login');
Route::post('login', [AuthenticatedSessionController::class, 'store']);
Route::middleware(['custom_auth'])->group(function () {
Route::get('/dashboard', function () {
return Inertia::render('Dashboard');
})->name('dashboard');
});
class CustomAuthMiddleware
{
public function handle(Request $request, Closure $next)
{
if (session()->has('user_data')) {
return redirect(RouteServiceProvider::HOME);
}
return $next($request);
}
}
This works:
namespace App\Http\Middleware;
class RedirectIfAuthenticated
{
public function handle(Request $request, Closure $next, ...$guards)
{
if (session()->has('user_data')) {
return redirect()->route('users.index');
}
return $next($request);
}
}
namespace App\Http\Middleware;
class CustomAuthMiddleware
{
public function handle(Request $request, Closure $next)
{
if (session()->has('user_data')) {
return $next($request);
}
return redirect('login');
}
}
Route::middleware('guest')->group(function () {
Route::get('register', [AuthController::class, 'register'])
->name('register');
Route::post('register', [AuthController::class, 'registerPost']);
Route::get('login', [AuthController::class, 'login'])
->name('login');
Route::post('login', [AuthController::class, 'loginPost']);
});
Route::middleware('custom_auth')->group(function () {
Route::get('/', function () { return redirect()->route('users.index'); });
Route::resource('users', UserController::class);
});
I'm trying to config an user/admin environment in my laravel page, and whenever I try group the routes, I'll get one of the mentioned error back. What am I doing wrong? I tried both formats, same error.
web.php
//supposed user dashboard
Route::group(['middleware' => ['auth', 'user']], function () {
Route::get('/dashboard', 'DashboardController#index')->name('dashboard');
});
//supposed admin dashboard
Route::group(['middleware' => ['auth', 'admin']], function () {
Route::get('/dashboard', [AdminDashController::class, 'index']);
});
eg AdminDashController:
public function index()
{
return view("admin_dashboard");
}
DashboardController does the same, but returning user view.
I'm new to laravel, I appriciate any help!
Update:
I tried the solution below, my result is that I'm now getting "Route [user.dashboard] not defined." error...
My web.php
Route::group(['middleware' => ['auth', 'user']], function () {
Route::get('/dashboard', [UserDashController::class, 'index'])->name('user.dashboard');
});
// admin dashboard
Route::group(['middleware' => ['auth', 'admin']], function () {
Route::get('/dashboard', [AdminDashController::class, 'index'])->name('admin.dashboard');
});
my AdminDashController and UserDashController:
public function index()
{
return view('user_dashboard');
}
AND
public function index()
{
return view('admin_dashboard');
}
I have a RedirectIfAuthenticated.php
public function handle(Request $request, Closure $next, ...$guards)
{
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
/** #var User $user */
$user = Auth::guard($guard);
// to admin dashboard
if ($user->hasRole('admin')) {
return redirect()->route('admin.dashboard');
}
// to user dashboard
else if ($user->hasRole('user')) {
return redirect(route('user.dashboard'));
}
}
}
return $next($request);
}
Also having an Admin and User redirect:
AdminAuthenticated.php:
public function handle(Request $request, Closure $next)
{
if( Auth::check() )
{
/** #var User $user */
$user = Auth::user();
// if user is not admin take him to his dashboard
if ( $user->hasRole('user') ) {
return redirect()->route('user.dashboard');
}
// allow admin to proceed with request
else if ( $user->hasRole('admin') ) {
return $next($request);
}
}
abort(403); // permission denied error
}
UserAuthenticated
public function handle(Request $request, Closure $next)
{
if( Auth::check() )
{
/** #var User $user */
$user = Auth::user();
// if user is admin take him to his dashboard
if ( $user->hasRole('admin') ) {
return redirect(route('admin.dashboard'));
}
// allow user to proceed with request
else if ( $user->hasRole('user') ) {
return $next($request);
}
}
abort(403); // permission denied error
}
Update 2:
I replaced the routing in web.php as follows:
Route::middleware(['auth','user'])->group(function () {
Route::prefix('user')->group(function () {
Route::get('/dashboard', [UserDashController::class, 'index'])->name('user.dashboard');
});
});
Route::middleware(['auth','admin'])->group(function () {
Route::prefix('admin')->group(function () {
Route::get('/dashboard', [AdminDashController::class, 'index'])->name('admin.dashboard');
});
});
Still same error: "Route [user.dashboard] not defined."
The problem may be in your route name. One route has a named dashboard another was not. Use the below code hope this will resolve your problem
// user dashboard
Route::group(['middleware' => ['auth', 'user']], function () {
Route::get('/dashboard', 'DashboardController#index')->name('user.dashboard');
});
// admin dashboard
Route::group(['middleware' => ['auth', 'admin']], function () {
Route::get('/dashboard', 'DashboardController#index')->name('admin.dashboard);
})
use the route name in stead of url.
in my case, instead using your code below :
Route::group(['middleware' => ['auth', 'user']], function () {
Route::get('/dashboard', [UserDashController::class, 'index'])->name('user.dashboard');
});
// admin dashboard
Route::group(['middleware' => ['auth', 'admin']], function () {
Route::get('/dashboard', [AdminDashController::class, 'index'])->name('user.dashboard');
});
i use my own code, so define the middleware first and use prefix on it :
Route::middleware(['auth','user'])->group(function () {
Route::prefix('user')->group(function () {
Route::get('/dashboard', [UserDashController::class, 'index'])->name('user.dashboard');
});
});
Route::middleware(['auth','admin'])->group(function () {
Route::prefix('admin')->group(function () {
Route::get('/dashboard', [AdminDashController::class, 'index'])->name('admin.dashboard');
});
});
maybe you should differentiate routing between dashboard for admin and user. you can use like this : /admin/dashboard and /user/dashboard
edit :
i think there's some typo on your code :
// to admin dashboard
if ($user->hasRole('admin')) {
return redirect(route('admin.dashboard'));
}
return redirect route should typed like this : return redirect()->route('admin.dashboard)
Hello i tried to use middleware like the code below to validate OR operator
Route::get('/page', [Controller::class, 'index'])->middleware(['mid1','mid2']);
in this example it uses the AND operator not OR I used also groups like this
Route::group(['middleware' => 'mid1'], function () {
Route::get('/page', [Controller::class, 'index']);
});
Route::group(['middleware' => 'mid2'], function () {
Route::get('/page', [Controller::class, 'index']);
});
but using groups with same route the second route in the group is the only one readable.
Any help please
There's nothing builtin in laravel to do such a thing.
You can create another middle-ware to contain both conditions you need to apply.
In you middleware:
public function handle($request, Closure $next) {
if (condition1 || condition2) {
return $request($next);
}
abort('statusCode');
}
I agree with #Faesal. It would be best to combine two middleware logic into one middleware.
public function handle($request, Closure $next) {
if (your condition) {
//logic inside mid1 handler
}else{
//logic inside mid2 handler
}
}
Although it is not recommended but you can put your conditions in route file.
if(your conditions){
Route::group(['middleware' => 'mid1'], function () {
Route::get('/page', [Controller::class, 'index']);
});
}else{
Route::group(['middleware' => 'mid2'], function () {
Route::get('/page', [Controller::class, 'index']);
});
}
so im trying to put my localization as prefix on my website domain so i made a middleware the puts the localization lang on the url ever time you try to open a page heres my middleware
public function handle($request, Closure $next)
{
if ($request->method() === 'GET') {
$segment = $request->segment(1);
if (!in_array($segment, config('app.locales'))) {
$segments = $request->segments();
$fallback = session('locale') ?: config('app.fallback_locale');
$segments = array_prepend($segments, $fallback);
return redirect()->to(implode('/', $segments));
}
session(['locale' => $segment]);
app()->setLocale($segment);
}
return $next($request);
}
and i added the middleware to the routemiddleware
protected $routeMiddleware = [
'Locate' => \App\Http\Middleware\Locale::class,
];
and i did put a prefix and middleware to all my routes like this
Route::prefix('{lang?}')->middleware('Locate')->group(function() {
Route::get('logout', '\App\Http\Controllers\Auth\LoginController#logout')->name('logout');
Route::get('/home', 'HomeController#index')->name('home');
Route::get('/admin/login', function () {
return view('admin.auth.login');
})->name('AdminLogin');
Route::get('/contact-us', 'ContactUsController#Contactus')->name('ContactUs');
Route::post('/contact-us', 'ContactUsController#PostContactus')->name('PostContactUs');
Route::prefix('auth')->group(function () {
Route::get('/login', function () {
return view('auth.login');
})->name('Login');
Route::post('/login', 'Auth\LoginController#Login')->name('userslogin');
});
Route::prefix('search')->group(function () {
Route::get('/categories', 'search\SearchController#Categories')->name('Categories');
Route::get('/filter/{categoryseo}', 'search\SearchController#filter')->name('InstructorsSearch');
//sending categoryseo to the filter page so i can put it in hidden input in the filter page and use it to get the list
Route::get('/list', 'search\SearchController#InstructorList')->name('InstructorsSearchList');
Route::get('/profile/{userid?}', 'search\SearchController#instructorprofile')->name('InstructorProfile');
});
});
for some reason pages like /home gets the to the middleware and change as i wanted like this /en/home , as for other like search/categories it wont even notice my middleware but i tried to remove the prefix of the localization and just put my middleware it worked and it notice my middleware. using laravel 5.5
Let's say I have the following routes file:
Route::group(['middleware' => 'foo.only'], function () {
Route::get('/', 'FooController#index');
Route::get('/about', 'FooController#about');
});
Route::get('/', 'BarController#index');
Route::get('/about', 'BarController#about');
In my FooOnlyMiddleware handler I have something like:
public function handle($request, $next)
{
if ($foo == true) {
return $next($request);
}
else {
// skip the entire route group and move onto the next route
}
}
How do I do this so that if $foo = false it will skip the entire route group and move onto the bar routes?
This won't work, as both of your foo and bar routes are the same:
Route::get('/', 'FooController#index');
Route::get('/', 'BarController#index');
The bar route will never be reached.
Here is one way to accomplish the conditional routes you want:
Your routes:
Route::group(['middleware' => 'foo.only'], function () {
Route::get('/', 'FooController#index');
Route::get('/about', 'FooController#about');
});
Route::get('bar/', 'BarController#index');
Route::get('bar/about', 'BarController#about');
FooOnlyMiddleware:
public function handle($request, $next)
{
if ($foo == true) {
return $next($request);
}
else {
return redirect('/bar/'.$request->route()->uri());
}
}
Of course, this would be valid if every route using the FooOnlyMiddleware, has an equivalent bar route. Otherwise, just redirect to any route you want.