I created a middleware to check if a user is admin or editor, but for some reason in my if statement when i use the OR operator to check if the user has access, it doesnt work, it accepts the first property statement, but not after the OR operator.
To work i need to separate each condition of account type.
For example:
Code dont work:
public function handle($request, Closure $next)
{
if(Auth::user()->account_type_id == '1' || Auth::user()->account_type_id == '2') // is an admin
{
return $next($request); // pass the admin
}
return redirect('/admin'); // not admin. redirect whereever you like
}
Code that Works:
public function handle($request, Closure $next)
{
// dd($request->all());
if(Auth::user()->account_type_id == '1') // is an admin
{
return $next($request); // pass the admin
}
if(Auth::user()->account_type_id == '2') // is an admin
{
return $next($request); // pass the admin
}
return redirect('/admin'); // not admin. redirect whereever you like
}
Does anybody no whats wrong?
I would create an array and check the condition again the array of possible solutions.
public function handle($request, Closure $next)
{
$accountTypes = array('1','2');
if (in_array(Auth::user()->account_type_id, $accountTypes)) {
return $next($request); // pass the admin
}
return redirect('/admin'); // not admin
}
Try using the in_array function, this will also make your code more readable and easy to maintain.
public function handle($request, Closure $next)
{
if (in_array(Auth::user()->account_type_id, ['1', '2'])) // is an admin
{
return $next($request); // pass the admin
}
return redirect('/admin'); // not admin. redirect whereever you like
}
I don't know why the second one work but here is mine and it works fine give it a try
public function handle($request, Closure $next)
{
$user = $request->user();
if ($user->role == 1 || $user->role == 2) {
return $next($request);
}
else{
return redirect(url('/admin'));
}
}
Related
I'm new to laravel I have created middleware for my each role but when I add it to my route it won't work.
If I add single middleware to my route it works fine but when I add second and third one It will not work.
It won't shows the route to authorized user it redirect it to home,
My User Model:
public function IsAdmin()
{
if($this->role_id =='1')
{
return true;
}
else
{
return false;
}
}
public function IsManager()
{
if($this->role_id =='2')
{
return true;
}
else
{
return false;
}
}
public function IsUser()
{
if($this->role_id =='3')
{
return true;
}
else
{
return false;
}
}
My Kernal:
'IsAdmin' => \App\Http\Middleware\IsAdmin::class,
'IsManager' => \App\Http\Middleware\IsManager::class,
'IsUser' => \App\Http\Middleware\IsUser::class,
My IsAdmin Middlewares:
public function handle($request, Closure $next)
{
$user =Auth::User();
if(!$user->IsAdmin())
{
return redirect('stock');
}
return $next($request);
}
My IsManager
public function handle($request, Closure $next)
{
$user =Auth::User();
if(!$user->IsManager())
{
return redirect('stock');
}
return $next($request);
}
and IsUser
public function handle($request, Closure $next)
{
$user =Auth::User();
if(!$user->IsUser())
{
return redirect('stock');
}
return $next($request);
}
and finally my Route
Route::get('approv',['middleware'=>['IsManager','IsAdmin'],function(){
return view('approv');
}]);
This will not work as you'd expect. All middleware need to pass in order for the request to be processed which means that your user will need to be both a manager and an admin at the same time which based on your setup is impossible.
You can get around this (kind of) by making a different kind of middleware:
Kernel:
'roles' => \App\Http\Middleware\Roles::class,
And the Roles middleware:
class Roles {
private function checkRole($role) {
switch ($role) {
case 'user': return \Auth::user()->IsUser();
case 'manager': return \Auth::user()->IsManager();
case 'admin': return \Auth::user()->IsAdmin();
}
return false;
}
public function handle($request, Closure $next, ...$roles)
{
foreach ($roles as $role) {
if ($this->checkRole($role)) {
//At least one role passes
return $next($request);
}
}
//All checks failed so user does not have any of the required roles
return redirect('stock');
}
}
Then to use this you simply do:
Route::get('approv',['middleware'=>['roles:manager,admin'],function(){
return view('approv');
}]);
This works because Laravel Middleware support parameters. You can pass parameters as a comma separated list of strings where you declare the middleware. In this case this was done as roles:manager,admin
Laravel will then send these parameters as additional parameters in the handle method. These can be accessed using PHPs syntax for variadic arguments. In this particular case it's by using the array spread operator. This is documented as an example in the function arguments section of the PHP manual.
Note that this is actually equivalent to saying :
public function handle($request, Closure $next, $role1=null, $role2=null, $role3=null)
but using the spread operator is much more convenient since ...$roles would be an array which contains only the roles that were passed in the middleware.
I am using laravel quickadmin to create an admin section
https://github.com/LaravelDaily/quickadmin
It allows to create roles and users based on roles. How can i redirect users of a specific role into website and not admin.
Many thanks
change the following in the middleware
public function handle($request, Closure $next)
{
if ($request->user() != null && $request->user()->permissionCan($request)) {
return $next($request);
}
abort(403);
return false;
}
to (alter "specific role" and "your route" as you wish)
public function handle($request, Closure $next)
{
if ($request->user() != null && $request->user()->permissionCan($request)) {
$response = $next($request);
if( $request->user()->role() == 'specific role'){
redirect()->route('your route');
}
return $response;
}
abort(403);
return false;
}
Instead of the laravel multi auth I am using my own (primitive) method to have admin users.
I just have an extra table in the database called PAdmin and in this table I have the id's of the admin users.
When I log in to the application I want to redirect the admin users to another page instead of the home page.
For that reason, I went to Http\Middleware\RedirectIfAuthenticated and changed the code so from this :
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/home');
}
return $next($request);
}
I changed it to this :
public function handle($request, Closure $next, $guard = null)
{
$user_id = Auth::id();
$isAdmin = PAdmin::where('user_id',$user_id)->get()->isEmpty();//returns 'true' if empty
if (Auth::guard($guard)->check() && $isAdmin) {//IF $isAdmin is TRUE it means that the user is not admin
return redirect('/home');
}elseif (Auth::guard($guard)->check() && !($isAdmin)){//IF $isAdmin is FALSE it means that the user is not admin
return redirect('/admin');
}
return $next($request);
}
The idea is simple - if there is a record with the user's ID in the PAdmin table $isAdmin will be false and the elseif will execute.
Unfortunately this isn't working and I don't know why.
Maybe this isn't the right way to do it at all.
Can someone help me get this right.
P.S. I don't want to use multi auth.
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
if(PAdmin::where('user_id',Auth::id())->first() != null) return redirect('/admin');
return redirect('/home');
}
return $next($request);
}
More clear and easier.
I created two Middleware called "MustBeAdmin" and "MustBeUser" to make sure depending on the user login I redirect them to the right page and restrict unauthorized content. Currently everything is working fine and redirects work well too. But the Logic I wrote behind the scene seems wrong to me and its weird it still works. If I write the logic that seems right to me atleast, it does not seem to work as expected.
Users table
id (1,2,3,...)
name
role (1,2,3,...)
Roles table
id (1,2,3,...)
role (Student, Admin,...)
MustBeAdmin middleware
public function handle($request, Closure $next)
{
if($request->user()->role == 2)
{
return $next($request);
}
else
{
return redirect('/admin/users');
}
}
MustBeUser middleware:
public function handle($request, Closure $next)
{
if($request->user()->role == 1)
{
return $next($request);
}
else
{
return redirect('/admin/users');
}
}
kernel.php
'admin' => \App\Http\Middleware\MustBeAdmin::class,
'user' => \App\Http\Middleware\MustBeUser::class,
As you can see I have registered middlewares in kernel.
I am getting results exactly what I need but I doubt if the logic in middleware is correct?
1 = Student
2 = Admin
if you see in MustBeAdmin middleware I am comparing if user role is 2 (admin) then do next($request) and in MustBeUser middleware I am comparing if user role is 1 (Student) then do next($request) and I set else to /Admin directory.
I feel its wrong, what do you think?
You are not checking the authenticated users details in your Middleware. The middleware should be something like:
//for student
public function handle($request, Closure $next)
{
if ( Auth::check() && Auth::user()->role == 1 )
{
return $next($request);
}
return redirect('/admin');
}
//for admin
public function handle($request, Closure $next)
{
if ( Auth::check() && Auth::user()->role == 2 )
{
return $next($request);
}
return redirect('/student');
}
You should check my detailed answer on the same topic here
Yes, It can be handled in one common file.
Here is the code
public function handle($request, Closure $next)
{
$user = User::find(Auth::id());
$roles = [];
foreach ($user->roles as $key => $value) {
array_push($roles, $value->pivot->role_id);
}
$routeName = Route::getFacadeRoot()->current()->uri();
$route = explode('/', $routeName);
if ($route[0] == "teacher") {
if (in_array(2, $roles)) {
return $next($request);
} else {
return response('Unauthorized.', 401);
}
} elseif ($route[0] == "student") {
if (in_array(1, $roles)) {
return $next($request);
} else {
return response('Unauthorized.', 401);
}
} elseif ($route[0] == "admin") {
if (Auth::user()->admin == 1) {
return $next($request);
} else {
return response('Unauthorized.', 401);
}
} else {
if (!Auth::user()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('admin-panel/auth/login');
}
}
}
return $next($request);
}
You can alter the logic according to your need.
i want to show a 404 error page if the user try to access to de admin page if he is not logged or if he dont have the 'Admin' type. This work fine if the user is logged in, if not the user access to the admin panel. If i remove the if(Auth::check()) the script shows a Trying to get property of non-object error.
class AdminMiddleware {
public function handle($request, Closure $next)
{
if(Auth::check()){
if ($request->user()->type != 'Admin'){
return abort(404);
}
}
return $next($request);
}
}
Try this
class AdminMiddleware {
public function handle($request, Closure $next)
{
if(Auth::check()){
if ($request->user()->type != 'Admin'){
return abort(404);
}
}else{
return abort(404);
}
return $next($request);
}
}
It should check if user is logged in and if so check if hes and admin, if hes not logged in show him the 404
or a shorter version
class AdminMiddleware {
public function handle($request, Closure $next)
{
if(Auth::check() && $request->user()->type == 'Admin'){
return $next($request);
}
return abort(404);
}
}