Apply middleware when URL pattern matches in Laravel - laravel

I am trying to add a simple middleware to my project that checks if a user is allowed to access a project. My approach is:
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class UserProjectFit
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if ($request->is('*/projects/*')) {
$projectUserId = DB::table('project_user')
->where('project_id', '=', $request->project['id'])
->where('user_id', '=', Auth::user()->id)
->first();
if (is_null($projectUserId)) {
abort(404);
}
}
return $next($request);
}
}
It basically works, but I have also routes like e. g. projects/create and here the middleware kicks in too. The idea would be that the middleware only takes action in case the URL contains the string project and an id, e. g. …projects/1/…
What would be a good way to solve that? If my approach isn't good, I am happy to read your suggestions.

You can use authentication gates and associate them with role id. This can be done in the Authserviceprovider.
Something like this
Gate::define('projects_create_access', function ($user) {
return in_array($user->role_id, [1]);
});

I just followed the simple approach to attach the route to every route I need it. The details are:
Route:
Route::get('projects/{project}', 'ProjectsController#showProjectDashboard')->name('show-project-dashboard')->middleware('UserProjectFit');
Middleware:
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class UserProjectFit
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$projectUserId = DB::table('project_user')
->where('project_id', '=', $request->project['id'])
->where('user_id', '=', Auth::user()->id)
->first();
if (is_null($projectUserId)) {
abort(404);
}
return $next($request);
}
}
Kernel.php
protected $routeMiddleware = [
...
'UserProjectFit' => \App\Http\Middleware\UserProjectFit::class
];

Related

Laravel 9 route groups with two conditions

In my users table I have a field (boolean):
active
My routes currently use
Route::middleware(['auth'])->group(function ()
but I want to do is to add the active so they will have to be authorised and active.
I can't seem to find the answer.
Thanks in advance!
Add another middleware to group.
Route::middleware(['auth','active'])->group(function ()
You can implement that middleware like
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class Active
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* #return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
if (!$request->user()->active){
return redirect('login');
}
return $next($request);
}
}
Obviously you need to register this middleware into app/Http/Kernel.php
protected $routeMiddleware = [
....
'active' => \Illuminate\Auth\Middleware\Active::class,
]
I hope this help

how to get RouteName in Laravel 5

I want to get current route Name that is being used in current url in middleware. i tried many example that nothing is working. please share best way to get that route name in Middleware.
<?php
namespace App\Http\Middleware;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;
use Closure;
class PermissionMiddleware {
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next) {
$user = Auth::user();
$pemissions = getUserPermissions($user);
session(['permissions' => $pemissions]);
$defaultPermission = $this->defaultPermission($user->user_type, $user->is_super);
$defaultPermission[] ='admin';
session(['defaultPermission' => $defaultPermission]);
return $next($request);
}
You can get route name from current request
$request->route()->getName()
or
request()->route()->getName()
$request->route()->getName()

error "Target class [Wazawaza2Middleware] does not exist."

I want to use middleware in laravel but show that.
enter image description here
I think my code is right.
Wazawaza2Middleware.php
<?php
namespace App\Http\Middleware;
use Illuminate\Support\Facades\Auth;
use Closure;
class Wazawaza2Middleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::check()){
return $next($request);
}else{
return view('auth.login');
}
}
}
web.php
use App\Http\Middleware\Wazawaza2Middleware;
Route::get('topde', 'ReviewController#top')->middleware('Wazawaza2Middleware::class');
Kernel.php
protected $routeMiddleware = [
.
.
.
'wazawaza2' =>
\App\Http\Middleware\Wazawaza2Middleware::class,
];
You have an error in your web.php, should be:
use App\Http\Middleware\Wazawaza2Middleware;
Route::get('topde', 'ReviewController#top')->middleware(Wazawaza2Middleware::class);
OR (since you are aliasing it)
Route::get('topde', 'ReviewController#top')->middleware('wazawaza2');

Laravel 5.4: Passing a variable via Request to controller

Generally speaking this should be a rather simple problem. IT should be very similar to the following question on Stack Overflow
But seeing as it has been two years, maybe some of the syntax has changed.
All I want to do is pass a variable from the middleware to the controller, so I'm not duplicating mysql queries.
Here is my middleware:
namespace App\Http\Middleware;
use Closure;
class CheckRole
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$id = $request->user()->id;
$rr = $request->user()->isSuperAdmin();
if ($request->user()->isSuperAdmin()) {
$request->merge(['group' => 123]);
return $next($request);
}
echo "not admin";
}
}
So the middleware works fine and if I DD($request) on the middleware I see my group => 123 on the page. (Right now it's 123 for the sake of simplicity.)
So I want to pass it to my AdminController:
<?php
namespace SleepingOwl\Admin\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use SleepingOwl\Admin\Form\FormElements;
use SleepingOwl\Admin\Form\Columns\Column;
use SleepingOwl\Admin\Display\DisplayTable;
use Illuminate\Contracts\Support\Renderable;
use SleepingOwl\Admin\Display\DisplayTabbed;
use Illuminate\Validation\ValidationException;
use SleepingOwl\Admin\Contracts\AdminInterface;
use SleepingOwl\Admin\Model\ModelConfiguration;
use Illuminate\Contracts\Foundation\Application;
use SleepingOwl\Admin\Contracts\Form\FormInterface;
use SleepingOwl\Admin\Contracts\ModelConfigurationInterface;
use SleepingOwl\Admin\Contracts\Display\ColumnEditableInterface;
class AdminController extends Controller
{
/**
* #var \DaveJamesMiller\Breadcrumbs\Manager
*/
protected $breadcrumbs;
/**
* #var AdminInterface
*/
protected $admin;
/**
* #var
*/
private $parentBreadcrumb = 'home';
/**
* #var Application
*/
public $app;
/**
* AdminController constructor.
*
* #param Request $request
* #param AdminInterface $admin
* #param Application $application
*/
public function __construct(Request $request, AdminInterface $admin, Application $application)
{
$this->middleware('CheckRole');
So as you can see I call the middleware on this constructor. After calling it I should be able do something like:
$request->get('group'); or $request->group;
After trying for quite a while nothing seems to be working and I keep getting a null value. Fundamentally, this shouldn't be terribly difficult, but I seem to have my syntax off or not using the right name spaces?
Instead of this code line:
$request->merge(['group' => 123]);
You can try:
$request->request->add(['group' => 123]);
What this code line will do is if a parameter named group exists in the $request it will overwrite with the new value, otherwise it will add a new parameter group to the $request
In your controller, you can get the value of group parameter as:
$group = $request->group; OR $group = $request->input('group');
Thanks to the joint help of #Rahul-Gupta and #shock_gone_wild. It was a joint effort I guess.
The first issue is that I'm using sleepingOwl laravel boilerplate. Probably not the best idea for someone new to Laravel. (not new to MVC / PHP).
Based on #shock_gone_wild comment, decide move my test over to a simple controller, and not the sleeping owl nonsense. (they have a lot of code.) Anyways, I believe that helped. I did leave the middleware in the constructor because I didn't apply the middleware to the routes.
Then I followed #Rahul-Gupta syntax.
So here is final result, hopefully this will save someone sometime someday...
namespace App\Http\Middleware;
use Closure;
class CheckRole {
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next) {
if ($request->user()->isSuperAdmin()) {
$request->request->add(['group' => 123]);
return $next($request);
} else {
echo "not admin";
}
}
}
Then here is the simple controller.
use Illuminate\Http\Request;
use App\task;
use App\User;
use App\HasRoles;
class TaskController extends Controller {
public function __construct() {
// constructor code...
$this->middleware('auth');
$this->middleware('CheckRole');
}
public function index(Request $request) {
$group = $request->input('group');
echo "---->" . $group;
$tasks = Task::all();
return view('test_task', compact('tasks'));
}
}

Disable Login in Laravel 5.2

In Laravel 5.2, I have added has_login field in the users table.
Where do I add logic to prevent user logging in if has_login is value 0 in the users table? I use AuthController.php for authentication and use AuthenticatesAndRegistersUsers without using login() / authenticate() functions in AuthController.hp file. Login work fine.
I personally tend to do this in the middleware, but you can also do it outside of that.
Here's a middleware example:
<?php namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RequireHasLogin
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string|null $guard
* #return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check())
{
if (!Auth::guard($guard)->user()->has_login)
{
Auth::logout();
if ($request->ajax() || $request->wantsJson())
{
return response('Unauthorized.', 401);
}
return redirect()->guest('/auth/login');
}
}
return $next($request);
}
}
Though I think some people do this too:
Auth::guard()->attempt(["email" => $email, "password" => $password, "has_login" => true])
This should point you in the right direction -
https://laravel.com/docs/master/authentication#authenticating-users

Resources