Laravel 8 same route multiple middleware using OR condition - php

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']);
});
}

Related

Laravel routing with conditions

How does it(route:caching) work under hood and will it breake logic if I cached my routes.
I have a webhook which send me data to one single route. The data are difference only by objects fields. Will it correct to split it to different routes or I am need to make index method which will be redirect my logic by methods
Route::group(['namespace' => 'Webhook'], function () {
if (Request::has('message')) {
Route::post('/', 'WebhookController#message');
}
if (Request::has('callback_query')) {
Route::post('/', 'WebhookController#callback');
}
});
You can shorten the routes code to this:
Route::group(['namespace' => 'Webhook'], function () {
Route::post('/', 'WebhookController#handle');
});
And do the "heavy work" in the controller:
class WebhookController extends Controller
{
public function handle(Request $request)
{
if ($request->has('message')) {
return $this->message();
}
if ($request->has('callback_query')) {
return $this->callback();
}
}
public function message();
public function callback();
}
This is equivalent to:
Route::group(['namespace' => 'Webhook'], function () {
Route::post('/', function(Request $request) {
if ($request->has('message')) {
return (new WebhookController)->message();
}
if ($request->has('callback_query')) {
return (new WebhookController)->callback();
}
});
});
You can use middleware for such kind of logics.
Laravel Middleware

prefix and middleware not working for some reason. for some routes

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

Laravel middleware to skip route group

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.

Laravel Auth redirect not working

I am using Laravel v5.2.39. I want to redirect to dashboard only, if you are logged in. If you change URL manually, it will redirect you to home screen. I am using auth middleware, but it doesn't work. Any help?
My routes.php file:
Route::get('/', function () {
return view('welcome');
})->name('home');
Route::get('dashboard', [
'uses' => 'UserController#getDashboard',
'as' => 'dashboard',
'middleware' => 'auth'
]);
My UserController.php:
public function getDashboard(){
return view('dashboard');
}
And auth middleware:
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()->route('home');
}
}
return $next($request);
}
I don't know, whats the problem with. I have some sign in and sign up too, but i dont think this is problem. If somenone wanna see it, write me.
Have a nice day and thank you.
As mentioned above, have you tried something like this?
Route::group(['middleware' => 'auth'], function () {
Route::get('dashboard', 'UserController#getDashboard')->name('dashboard');
});
Or you can add the middleware in the construct function in your class like so :
public function __construct() {
$this->middleware('auth');
}
Also, see the laravel documentation on using middleware with routes.
Try using 'middleware' => 'auth:web' in place of 'middleware' => 'auth'
Hey im not clear about your problem but this will help you,
when you go for project path localhost/project/ it will redirect to localhost/project/home URL in that URL u can assign any function
Route::get('/', function () {
return redirect('home');
});

Laravel controllers filter issue

I have this filter method defined in filters.php
Route::filter('auth', function()
{
if (Auth::guest())
{
if (Request::ajax())
{
return Response::make('Unauthorized', 401);
}
else
{
return Redirect::guest('login');
}
}
});
when i add this code to controller
public function __construct()
{
$this->beforeFilter('auth');
}
it gives me the famous route exception of laravel at Illuminate\Routing\RouteCollection.php
Why do you want to put that in controller. You can attaching a filter to a route or controller in route.php. Let say you have multiple route that u want to check if the user guest or not. So, in routes.php you can define group filters. If you define that in controller you must attach the filter to every controller. See example below:
Route::group(array('before' => 'auth'), function()
{
Route::get('user/account', 'UserController#account');
Route::get('user/settings', 'UserController#settings');
Route::get('post/create', 'PostController#create');
Route::post('post/store', 'PostController#store');
// ...
});
Example
Auth Filter
Route::filter('auth', function()
{
if (Auth::guest()) return Redirect::guest('login');
});
Attaching Auth Filter to controller
Route::get('user', array('before' => 'auth', 'uses' => 'UserController#showProfile'));

Categories