I have 2 Middlewares.
My StaffMiddleware
public function handle($request, Closure $next)
{
if( $request->user()->role->name != 'staff'){
return redirect()->route('store');
}
return $next($request);
}
My AdminMiddleware
public function handle($request, Closure $next)
{
if( $request->user()->role->name != 'admin'){
return redirect()->route('store');
}
return $next($request);
}
The Problem is my UnitController
public function __construct(UnitInterface $unit){
$this->middleware('staff');
$this->middleware('admin);
$this->unit = $unit;
}
It should work either the role is a staff or an admin. Do I need to create another Middleware to combine them both?
This completely depends on the way your Middleware is designed. As you can see from your code, it simple redirects if the role is not staff or not admin so there would be no way for you to have an OR logic.
However, you could use middleware parameters to avoid this.
$this->middleware('role:admin,staff');
This will use the role middleware and pass admin and staff as parameters.
Then you can use these parameters in your middleware:
public function handle($request, Closure $next, ...$params)
{
if(!in_array($request->user()->role->name, $params)){
return redirect()->route('store');
}
return $next($request);
}
This captures the additional parameters into an array $params in which you can check if the user's role matches one of the parameters.
**try this**
public function __construct(UnitInterface $unit){
$this->middleware(function ($request, $next) {
if($request->user()->role->name == 'staff' || $request->user()->role->name == 'admin')
{
return $next($request);
}
return redirect()->route('store')
});
}
No middleware
Related
I have a relationship between users and roles. In middleware, I need to get roles to check if the role is 1 or 2. However, I get the following error.
"Trying to get property 'role_id' of non-object."
I am sure I have id 1 in role_id.
User Model
public function role()
{
return $this->belongsTo(Role::class, 'role_id');
}
public function handle($request, Closure $next)
{
if (!Auth()->check() && $request->user()->role_id == 1) {
return redirect()->back();
}
return $next($request);
}
Your if statement's logic is mistakenly checking if the user is logged out, while also checking the user's roles. If Auth::check() is false, then the user is not logged in and $request->user() will return null.
Removing the ! from the conditional will fix the error you're receiving.
public function handle($request, Closure $next)
{
if (Auth()->check() && $request->user()->role_id == 1) {
return redirect()->back();
}
return $next($request);
}
However, this will allow all guests to proceed, which you may not want. Assuming you want the middleware to only allow logged-in users with a specific role to proceed, use a more white-listed approach like this:
public function handle($request, Closure $next)
{
// Role ID 2 has permission to proceed
if (Auth()->check() && $request->user()->role_id == 2) {
return $next($request);
}
// Everyone else should go back, including logged-in users and guests.
return redirect()->back();
}
[Can't comment so I'm making a post.]
Aken already answered you but I'd suggest one more thing. Don't use 1 or 2 as ID's but constants:
public function handle($request, Closure $next)
{
if (Auth()->check() && $request->user()->role_id == ADMIN) {
return $next($request);
}
return redirect()->back();
}
You don't even need the comments for this one. Maybe even better:
public function handle($request, Closure $next)
{
if (Auth()->check() && $request->user()->isAdmin()) {
return $next($request);
}
return redirect()->back();
}
but you need to implement it on your own.
this my middleware:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckSession
{
public function handle($request, Closure $next)
{
return $next($request);
}
public function CheckSessionPageReuestTokenFailed($request, $next)
{
if ($request->session()->has('request_failed')) {
return $next($request);
} else {
echo 'forbidden';
}
}
}
how i can use method CheckSessionPageReuestTokenFailed($request, $next)?
thanks
Why you have written this method ?. you can write this code into handle method.
public function handle($request, Closure $next)
{
if ($request->session()->has('request_failed')) {
return $next($request);
} else {
echo 'forbidden';
}
}
and also you need register this middleware into $routeMiddleware array in
app/Http/Kernel.php file.
add this line:
'CheckSession' => CheckSession::class,
read laravel documentation to know more https://laravel.com/docs/5.4/middleware
public function handle($request, Closure $next)
{
$this->CheckSessionPageReuestTokenFailed($request, $next);
return $next($request);
}
You can use inside handle() method.
public function handle($request, Closure $next)
{
$this->CheckSessionPageReuestTokenFailed($request, $next);
return $next($request);
}
I have two levels in middleware and it does not work well, then how to write middleware in two levels at once?
public function __construct()
{
$this->middleware('auth');
$this->middleware('Admin');
$this->middleware('Teacher');
}
I also have this, i want to check that this page is only accessible by admin and teacher, but in writing the code it does not work well and how to write it right?
#if (Auth::check() && Auth::user()->level == 'Admin')
#elseif (Auth::check() && Auth::user()->level == 'Teacher')
#endif
If you can help me in solving this problem i am very grateful
in my experience i did that using a middleware ..
Middleware
public function handle($request, Closure $next, $roles)
{
$roles = explode('|',$roles);
$user = User::find($request->user()->id);
foreach($user->intRoles as $myRole)
{
if(in_array($myRole->role_id, $roles))
{
return $next($request);
}
}
return redirect()->back();
}
Route
Route::group( ['middleware' => 'rolePermissions:1|2|3'], function(){
Route::get('/users',['as'=>'users', 'uses'=>'PagesController#users']);
});
mydomain.com/users will only be accessible for those users who have roles (id) of 1, 2, or 3 ..
You have 2 separate middleware for checking user level. This forces both the conditions and doesn't work the way you want. You need a single middleware to check the user level and pass parameters to it.
Assume we have this middleware named as access.
public function handle($request, Closure $next, $levels)
{
$userLevels = explode(',', $levels);
if (Auth::check() && in_array(Auth::user()->level, $userLevels)) {
return $next($request);
}
return redirect('/home');
}
In your controller add this
public function __construct()
{
$this->middleware(['auth', 'access:Admin,Student']);
}
I have a role middleware that passes a parameter to the middleware.
public function __construct(UserInterface $user, RoleInterface $role, MaritalStatusInterface $maritalStatus, CityInterface $city){
$this->middleware('auth');
//$this->middleware('role:System Admin'); I changed it to 6 for the id.
$this->middleware('role:6');
}
My RoleMiddleware is this
public function handle($request, Closure $next, ...$params)
{
$roles = $request->user()->roles()->get();
$roles = $roles->map(function($item){
return $item->id;
});
foreach ($params as $value) {
if( ! in_array($value, $roles->toArray())){
return redirect()->action('NavController#home');
}
}
return $next($request);
}
As you can see I it is very tied to 6. What if I want to add 7... I want to make it dynamically. My tables are Users Role_User and Roles. What table do I need and how to execute it.
since you want it dynamically you should have a database for the allowed roles .. then in the same controller you should do
$allowedRoles = AllowedRoles::all();
$loop=1;
foreach($allowedRoles as $role)
{
$roleString = $loop == 1 ? $role->value : $roleString.'|'.$role->value;
// where value is equivalent to the role of your role id in role database
$loop++;
}
$this->middleware('role:'.$roleString);
then in your middleware you should explode the roleString
public function handle($request, Closure $next, $roles)
{
$roles = explode('|',$roles);
$user = User::find($request->user()->id);
foreach($user->intRoles as $myRole)
{
if(in_array($myRole->role_id, $roles))
{
return $next($request);
}
}
// Redirect
return redirect()->back();
}
I need to check the user is logged in and check their username in my Middleware of which verifies if they are an admin or not to limit access to a certain page. How do I get their username?
Using Auth::user() gives me an error from another Middleware.
ErrorException in VerifyCsrfToken.php line 136:
Trying to get property of non-object
Route
Route::get('admin', ['middleware' => 'admin', function() {
echo "You're an admin!";
}]);
Middleware
class VerifyAdmin
{
public function handle($request, Closure $next, $guard = null)
{
if (Auth::user()->username == "enayet123")
return $next($request);
}
}
You have to return
return $next($request);
even if your conditional fails so the next middleware can have the request. If you move that outside the conditional if, that should fix your problem.
Your code should look like this:
class VerifyAdmin
{
public function handle($request, Closure $next, $guard = null)
{
if (Auth::user()->username == "enayet123") {
// Do the thing you want ... (return or redirect to somewhere else)
redirect()->route('homepage');
}
return $next($request);
}
}
You should always return $next($request) which is necessary to pass the code / request from a particular middleware
In order to get the users details such as username/email you need to use $request->user() rather than Auth::user()
You should then check if the user is an admin by creating a method within the User model and calling that in the Middleware
class VerifyAdmin
{
public function handle($request, Closure $next, $guard = null)
{
$user = $request->user();
if ($user && $user->isAdmin()) {
return $next($request);
}
return redirect('/');
}
}