Restrict route access to non-admin users
Solution 1
You can use Middleware for this simple case.
- Create middleware:
php artisan make:middleware AdminMiddleware
namespace App\Http\Middleware;
use App\Article;
use Closure;
use Illuminate\Contracts\Auth\Guard;
class AdminMiddleware
{
/**
* The Guard implementation.
*
* @var Guard
*/
protected $auth;
/**
* Create a new filter instance.
*
* @param Guard $auth
* @return void
*/
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($this->auth->getUser()->type !== "admin") {
abort(403, 'Unauthorized action.');
}
return $next($request);
}
}
- Add it to
app\Http\Kernel.php
:
protected $routeMiddleware = [
'admin' => 'App\Http\Middleware\AdminMiddleware',
];
- Use middleware in your routes:
Route::group(['middleware' => ['auth', 'admin']], function() {
// your routes
});
Solution 2
This answer is about why your code doesn't work as expected. @limonte 's solution is correct and the best I can think of.
Your routes file is parsed to get your routes, and after that, those routes might be cached somewhere else.
Thus you shouldn't put any code that depends on the request (eg checking whether a User has sufficient rights to access a route).
In particular, you shouldn't use the following request dependent modules inside your routes.php (not exhaustive) :
Auth
-
DB
or any kind of db queries that might depend on time Session
Request
You should view your routes.php as part of your config, it just happens that it is written in php directly instead of some new language you have to learn.
Tiffany Soun
Updated on July 01, 2022Comments
-
Tiffany Soun over 1 year
Goal
I'm trying to create Admin route restriction for my log-in users. I've tried a check to see if my user is
log-in
, and also if the user type isAdmin
, and if they are, I want to allow them access to the admin route, otherwise, respond a 404.
routes.php
<!-- Route group --> $router->group(['middleware' => 'auth'], function() { <!-- No Restriction --> Route::get('dashboard','WelcomeController@index'); <!-- Admin Only --> if(Auth::check()){ if ( Auth::user()->type == "Admin" ){ //Report Route::get('report','ReportController@index'); Route::get('report/create', array('as'=>'report.create', 'uses'=>'ReportController@create')); Route::post('report/store','ReportController@store'); Route::get('report/{id}', array('before' =>'profile', 'uses'=>'ReportController@show')); Route::get('report/{id}/edit', 'ReportController@edit'); Route::put('report/{id}/update', array('as'=>'report.update', 'uses'=>'ReportController@update')); Route::delete('report/{id}/destroy',array('as'=>'report.destroy', 'uses'=>'ReportController@destroy')); } } });
Result
It's not working as I intended. It throws 404 error - even for Admin users.
-
user1669496 almost 9 yearsAre you caching your routes?
-
-
Khan Shahrukh almost 9 yearsthat was pretty quick I must say ! And perfect answer
-
Harry Geo almost 9 yearsAlso a more "clean" approach is to place the middleware inside your Controller's constructor. But that's up to you
-
NULL pointer over 5 yearsIf you put the middleware in your controller, you run into the problem of the Guard passed into the middleware constructor as $auth has a null user property, even when you are logged in. \Auth::user() is also null in both the constructor and the handle method of the created middleware. This forced me to have to check the user's access inside each method called by the routes, not in the controller's constructor. The route caching issue will be OK for 99% of cases, but to be truly secure I think checking inside each method is needed. A bit of a pain, if anyone knows a better way, let me know
-
KTM over 4 yearsI have to mention that Enable middleware in your controller, using middleware's key, not class name: $this->middleware('admin'); Step is missing here. Thanks