Laravel: Check if User is an admin using isAdmin column? - php

I'm really new to laravel and have been reading the documentations and tutorials. I'm planning on making an app that has 2 roles, admin and user. I modified my User model to have the column 'isAdmin' with boolean value since I only need 2 roles. How do I perform a check on this attribute during auth? Thank you.

TO answer your question, first of all to make protect any route using the auth middleware which ensures a user is authenticated (logged in) before they can access the route, you simply need to add the auth middleware.
e.g
web.php
<?php
Route::middleware('auth')->group(function(){
//All Routes which needs user to be logged in
});
or
//Individiual Route Middleware
Route::get('/path/to', 'controller#instance')->middleware('auth');
As for checking user role, you can basically create a middleware for this using the following steps:
run your php artisan make:middleware IsAdminMiddleware
open your IsAdminMiddleware and add this code inside the handle function:
public function handle($request, Closure $next)
{
if(!Auth::check()){
return redirect()->route('login');
}
if(Auth::user()->isAdmin == true){
return $next($request);
}
return redirect()->back()->with('unauthorised', 'You are
unauthorised to access this page');
}

Related

Showing subpages based on a session in Laravel 5.8

I am begginer in Laravel. I am use Laravel 5.8 in my project.
I need to do something so that a specific route can be viewed by a user with a php adult = 1 session.
I have route:
Route::get('/', 'FrontendController#index')->name('index');
Route::get('/sample1', 'FrontendController#sample1')->name('sample1');
The SAMPLE1 view is for users with php adult = 1 session.
If the user does not have such a session - it must be automatically redirected to # index
How can you do this?
You can achieve this by creating a custom middleware, take a look at the documentation here:
https://laravel.com/docs/5.8/middleware
Instead of using session, you can maintain a user is adult or not on the users table, which means you can access this info via authenticated user (which is available throughout the whole app).
For e.g. in your app, use php artisan make:auth and this will scaffold out everything you need to for a register/login system. Before you run the migration, add a new field to the create_users_table migration, e.g. $table->boolean('adult')->default(false);
Then once the migration is ran, you can create a new middleware using: php artisan make:middleware CheckAdult with something like this:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckAdult
{
public function handle($request, Closure $next)
{
if (!auth()->check() || !auth()->user()->adult) {
return redirect('/');
}
return $next($request);
}
}
The above middleware will redirect anyone who is not logged in or have adult = 0 back to index page, otherwise continue with their request.
Then register the middleware and use it in the routes; as per the documentation.
you can use auth and middleware to achieve this. the simple logic would be something like this: $id = Auth::user()->adult; in your controller to check for users. ofcorse adult is a field in your table.
//on top of your controller place this
public function __construct()
{
$this->middleware('auth');
}
//control logic to check user
if($adult==1){
//perform unique task
}else{
return redirect('/')->with('message','You are not permitted')
}

how to block Url to all user except super admin

it should forbid that the user grabs this url:
?main_title=banner
?main_title=law
?main_title=faq
with this
if(\Auth::user()->hasRole(['super_admin']))
I am going to assume that you are using spatie/laravel-permission based on your example code.
Laravel Permission comes with built-in role middlewares
One of the ways you could use them is by grouping the routes you want to be accessible only by super admins
Route::group(['middleware' => ['role:super_admin']], function () {
// YOUR ROUTES HERE
});
It's always good to using the middlewares ,
So in your case first create a Trait for roles
public function isSuperadmin(){
return Auth::user()->role->role=='superadmin';
}
After that create a middlewar like superadmin for the superuser and in that first include your trait
use App\Traits\Roles;
after that
use Roles;
public function handle($request, Closure $next)
{
if(!$this->isSuperadmin())
{
return back();
}
return $next($request);
}
and just register the middleware in the app/http/kernal.php in protected $routeMiddleware function
'superadmin' => \App\Http\Middleware\superadmin::class,
so it's make your life very easy now you don't need to check the url or role every time , for any url you want to block for other users just use
Route::get('/?main_title=law', 'HomeController#function')->middleware('superadmin')->name('admin-dashboard-home');
so if the user role is superadmin then he is allow to assess the url you can redirect the other users or show the error message :)

Laravel Multiple Middleware in Route with OR Condition

I wonder if I can do this in Laravel Route. Let's say I have Admin, Premium and User (which can be login too by using Auth) Middleware. Also, I have controller with methods like this: index, create, edit, delete and I want Admin to be able do all those things, but Premium can only be able to access index method, and User can't access anything in this controller (he can access another controller). I know I can use except or only middleware method like this:
public function __construct()
{
$this->middleware('premium')->only('index');
$this->middleware('admin');
// or maybe $this->middleware('admin')->except('index');
}
but when I try to put these two middlewares in __construct method they will start to conflict each other, it makes sense because index method can be access by Premium but then can't be access by the Admin itself. By the way, my middleware is simply checking:
if (Auth::check()) {
if (Auth::user()->role == 'Admin') {
return $next($request);
}
}
return redirect('/home');
So, back to my question, can I have OR Middleware so I can avoid conflict from multiple middleware (which is must be AND condition when they written at the same controller constructor)?
If you change up the way your logic is thinking a little bit, the answer becomes pretty easy. You can create new middleware that checks if it can access the specific method.
So create the following middleware 'CanAccessIndex':
if (Auth::check()) {
if (Auth::user()->role == 'Admin' || Auth::user()->role == 'Premium') {
return $next($request);
}
}
return redirect('/home');
Then, you can put that middleware on the index function (instead of the premium middleware) and put your admin middleware on everything EXCEPT index. Like so:
public function __construct()
{
$this->middleware('canAccessIndex')->only('index');
$this->middleware('admin')->except('index');
}
That's one way to do it.
You need middleware group for this, and to manage these hierarchy of access layer, you can simply use Route grouping.
I will demo an example of what I mean:
Say you have auth middleware general for authenticated users (i.e everybody), then another called premium for premium member, and admin for the Admin.
Then you'll group based on the access level:
Route::middleware('auth')->group(function(){
Route::middleware('premium')->group(function(){
Route::post('/create', 'HomeController#create')->middleware('admin');
Route::put('/update/{id}', 'HomeController#update')->middleware('admin');
Route::get('/index', 'HomeController#index');
Route::put('/delete/{id}', 'HomeController#delete')->middleware('admin');
});
});
So you can have general check in your middleware with a check. It would have been much easier if you have role level say 3 for admin and 2 for premium member. So we can have for the premium middleware:
public function handle($request, Closure $next)
{
return auth()->user->role >= 2
? $next($request)
: redirect('/home');
}
This is just an example. You can do further check based on your need but more importantly, ensure your admin middleware to checks the exact role level that is allowed.

Laravel middleware authentication

Currently to add authentication I use this in my routes file:
Route::middleware(['auth'])->group(function () {
});
But I want to also check for different routes if the user is an admin, so currently I do this and have a custom middleware file:
Route::middleware(['auth', 'admin'])->group(function () {
});
//
<?php
namespace App\Http\Middleware;
use Closure;
class Admin {
public function handle($request, Closure $next)
{
if ( Auth::check() && Auth::user()->isAdmin() )
{
return $next($request);
}
return redirect('dashboard');
}
}
This all works fine, but I noticed with the api middleware it uses this:
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Questions
How can I make a namespaced auth middleware like the api one 'auth:admin'
Where is the file located that sets the 'auth:api' middleware, I could not find it anywhere in the app folder
Is there any other ways to do multiple auth like editing the file config/auth.php and then separating the users between two tables, one for admins and one for other users.
auth:api is actually the basic auth middleware with the string api as a parameter. This means the user is authenticated using the api authentication guard
You could use auth:admin out of the box if you added a custom authentication guard for the admins.
The auth middleware accepts one parameters which is the guard(s) to use. As you can see in Illuminate\Auth\Middleware\Authenticate middleware.
You can add custom auth guards. So you can create auth:admin if you'd like. But I do think it's perfectly fine to use one middleware to verify that the user is who he is (authentication) and a second one to verify that the user is allowed to visit the page he/she wants to visit (authorization).

Entrust Route Protection in Laravel 5 - Check for Auth first

For some reason I have had a mind block and can't figure out what is probably a very simple fix.
I have a Laravel 5 App and am using Zizaco's Entrust package for Access Control.
I want to protect a route so am using route Protection in routes.php as follows:
Entrust::routeNeedsRole('passtypes', array('admin'), null, false);
Which works as expected, apart from when a user's session has expired or they are not logged in and try to access the route.
In this case I would want Laravel's Authentication to be checked first, and redirect to the login page; however Entrust redirects to the 403 error first; which is confusing for a user that has ability to view that page, but is told they do not have access, rather than that they are not logged in/session has expired.
I initiate the Authentication in the Controller rather than in the route:
public function __construct()
{
$this->middleware('auth');
}
So just need to know how to get the same functionality, but by having auth get checked before the route permission requirement.
Thanks
I think that Entrust::routeNeedsRole fires before controller. Can you move Entrust to middleware? You could then check in middleware if user is logged in and then check if he has required role.
It's been a while, but I had a similar problem. The only difference, my entire app had to be protected. I ended up modifying Authenticate Middleware handle method:
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
/**
* This is to protect the entire app, except login form,
* to avoid loop
*/
if($request->path() != 'auth/login')
return redirect()->guest('auth/login');
}
}
return $next($request);
}
And inside Kernel.php moved Authenticate from $routeMiddleware to $middleware
Then you can protect your routes with Entrust.

Categories