I have a method for checking if a user's role is an admin, if not, redirect them with return redirect('/')->send();. How can I check for user role and redirect the user without displaying the page and waiting for a redirect?
My Controller:
class AdminController extends Controller
{
public function __construct()
{
if (Auth::check())
{
$user = Auth::user();
if ($user->role != 'admin')
{
return redirect('/')->send();
}
}
else
{
return redirect('/')->send();
}
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return View('admin/index');
}
}
Create your own Middleware. Here is an example. In my example, I have several usergroups in a separate model. You have to change the code for your needs.
Create the Middleware via terminal/console:
php artisan make:middleware UserGroupMiddleware
The created middleware class could be find in app/Http/Middleware/UserGroupMiddleware.php
You need the following code in your middleware:
namespace App\Http\Middleware;
use Closure;
use App\User;
use App\Usergroup;
class UserGroupMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next, $group)
{
if($request->user() !== NULL){
$userGroupId = $request->user()->group;
$userGroup = Usergroup::find($userGroupId);
if($userGroup->slug === $group){
return $next($request);
}
}
// Redirect the user to the loginpage
return redirect('/login');
}
}
Now you have to register this middleware in app/Http/Kernel.php:
protected $routeMiddleware = [
// other middlewares
// Custom Middleware
'group' => \App\Http\Middleware\UserGroupMiddleware::class
];
Finally you need to attach the middleware to your route:
Route::group(['middleware' => 'group:admin'], function(){
// Routes for admins, e.g.
Route::get('/dashboard', 'SomeController#dashboard');
});
// Or for a single route:
Route::get('/dashboard', ['middleware' => 'group:admin'], function(){
return view('adminbereich.dashboard');
});
Remember, that you could pass in multiple middlewares with:
Route::get('/some/route', ['middleware' => ['group:admin', 'auth']], 'SomeController#methodXYZ');
import redirect by adding this to the above the class
use Illuminate\Support\Facades\Redirect;
And the make your redirect by using
return Redirect::to('login');
Related
I am studying multiple authentication.
In particular I have 3 users:
a User user who must be redirected to /home when logging in
an Admin user who must be redirected to /admin/home when logging in
a Manager user who must be redirected to /manager/home when logging in
The problem I am having is when I log in as Admin and as Manager I am redirected to the route /home and then I get the error
["You do not have permission to access for this page."]
However, once I log in, if I manually enter the route of interest I can log in without problems.
So the problem is the route addressing once I try to log in as Admin or as Manager.
For the User user I'm not having any problems.
This is my code:
Route.php
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
/*------------------------------------------
--------------------------------------------
All Normal Users Routes List
--------------------------------------------
--------------------------------------------*/
Route::middleware(['auth', 'user-access:user'])->group(function () {
Route::get('/home', [HomeController::class, 'index'])->name('home');
});
/*------------------------------------------
--------------------------------------------
All Admin Routes List
--------------------------------------------
--------------------------------------------*/
Route::middleware(['auth', 'user-access:admin'])->group(function () {
Route::get('/admin/home', [HomeController::class, 'adminHome'])->name('admin.home');
Route::get('/admin/link', [HomeController::class, 'adminHello'])->name('admin.hello');
});
/*------------------------------------------
--------------------------------------------
All Admin Routes List
--------------------------------------------
--------------------------------------------*/
Route::middleware(['auth', 'user-access:manager'])->group(function () {
Route::get('/manager/home', [HomeController::class, 'managerHome'])->name('manager.home');
});
LoginController
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
public function login(Request $request)
{
$input = $request->all();
$this->validate($request, [
'email' => 'required|email',
'password' => 'required',
]);
if(auth()->attempt(array('email' => $input['email'], 'password' => $input['password'])))
{
if (auth()->user()->type == 'admin') {
return redirect()->route('admin.home');
}else if (auth()->user()->type == 'manager') {
return redirect()->route('manager.home');
}else{
return redirect()->route('home');
}
}else{
return redirect()->route('login')
->with('error','Email-Address And Password Are Wrong.');
}
}
}
HomeController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
return view('home');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function adminHome()
{
return view('adminHome');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function managerHome()
{
return view('managerHome');
}
}
UserAccess
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class UserAccess
{
/**
* 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, $userType)
{
if(auth()->user()->type == $userType){
return $next($request);
}
return response()->json(['You do not have permission to access for this page.']);
/* return response()->view('errors.check-permission'); */
}
}
Can you kindly help me?
In most of my applications I have an admin panel.
Here's how I do the redirect logic:
I use the default Auth/AuthenticatedSessionController class from the breeze install.
My store method looks like this:
public function store(LoginRequest $request)
{
$request->authenticate();
$request->session()->regenerate();
if (Auth::user()->hasRole('admin')) {
return redirect()->intended(RouteServiceProvider::ADMIN_HOME);
}
return redirect()->intended(RouteServiceProvider::HOME);
}
And of course in the RouteServiceProvider I hav my routes defined:
public const HOME = '/myorders';
public const ADMIN_HOME = '/admin/pages';
Solution 1:
On your App\Http\Controllers\Auth\LoginController, just override the method:
use Illuminate\Support\Facades\Auth;
public function redirectPath()
{
if (Auth::user()->role == 'Admin') {
return "/admin/home";
// or return route('admin.home');
}
elseif (Auth::user()->role == 'Manager') {
return "/manager/home";
// or return route('manager.home');
}
return "/home";
// or return route('home');
}
N.B: If something issue happenes with the method redirectPath, then please try with the method redirectTo. And must remove the property named redirectTo as well.
Solution 2:
App\Http\Controllers\Auth\LoginController.php
use Illuminate\Support\Facades\Auth;
protected function authenticated(Request $request, $user)
{
if (auth()->user()->hasRole(['Admin'])) {
return redirect("/admin/home");
}
elseif (auth()->user()->hasRole(['Manager'])) {
return redirect("/manager/home");
}
return redirect("/home");
}
N.B: If you are using Laravel Spatie Permission package, then the permission checking would work in this way.
i have 4 types of user which is 'admin', 'staff', 'lecturer', 'student'. i already made that when user login, it will redirect to the dashboard and i want to make the other 3 users to the booking page. supposedly with a simple if-else statement it can be done i believe. but tried doing it, it puts an error.
here are my AdminMiddleware.php:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AdminMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
if(Auth::user()->usertype == 'admin')
{
return $next($request);
}
else
{
return redirect('/booking')->with('status','you are not allowed to enter uitm dashboard');
}
}
}
and in my logincontroller.php, i do it like this:
protected function redirectTo()
{
if(Auth::user()->usertype == 'admin')
{
return 'dashboard';
}
else
{
return 'booking';
}
}
web.php:
Route::group(['middleware' => ['auth', 'admin']], function () {
Route::get('/dashboard', function () {
return view('admin.dashboard');
});
});
The ->name() at the end of the routes in case your redirect needs a name.
And the first line if you don't have it already. It will be the route for staff, lecturers, and students (admin can access too).
Route::get('/booking', /* code */)->name('booking');
Route::group(['middleware' => ['auth', 'admin']], function () {
Route::get('/dashboard', function () {
return view('admin.dashboard');
})->name('dashboard');
});
I have three roles in my application. I have a condition in which two roles can access same page. For that I write below code.
in below code, sub plan1 and sub plan 2 are roles.
Route::group(['middleware' => ['web', 'auth', 'SubPlan1', 'SubPlan2']], function () {
Route::get('/Parent-1-Info', '\ContactInfoController#Parent1Info'));
});
if sub plan1, tries to access the page, I get 404 error because i mentioned both middleware in same group.
Is there anyway to code such that I can define or condition in middleware?
For role based authentication I'm using this middleware:
namespace App\Http\Middleware;
use Auth;
use Closure;
use App\Role;
use Illuminate\Support\Collection;
class RoleMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next, $roles = null, $guard = null)
{
$roles = Role::whereIn('slug', explode('|', $roles))->get();
if (! Auth::guard($guard)->user()->hasRole($roles)) {
return abort(403, 'Forbidden');
}
return $next($request);
}
}
Then register the middleware in Kernel.php
'role' => \App\Http\Middleware\RoleMiddleware::class,
On the user model make sure you have a method to check if user has a set of roles, example:
public function hasRole($role)
{
if (is_int($role)) {
return $this->roles->contains('id', $role);
}
if (is_string($role)) {
return $this->roles->contains('slug', $role);
}
if ($role instanceof Model) {
return $this->roles->contains('id', $role->id);
}
return !! $role->intersect($this->roles)->count();
}
And you can use the middleware like this:
Route::group(['middleware' => ['auth', 'role:admin|staff'], ...);
You can replace admin|staff with your role names, separated by |. If you want to add custom guard then you can pass it as second parameter role:admin|staff,mycustomguard
Laravel 5.1 really had minimal documentation..
I need clear idea about how to protect routes using Auth middileware..
Documentation tells to add "middleware" => "auth" parameter to route.
or can do
public function __construct()
{
$this->middleware('auth');
}
But How to use Auth middleware for actual user authentication and auto redirection to /login from protected routes ??
In Kernel.php - there are registered middlewares under protected $routeMiddleware like this:
/**
* The application's route middleware.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => 'App\Http\Middleware\Authenticate',
'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
];
You can see 'auth' is registered for using App\Http\Middleware\Authenticate.
Then you can follow this path - if you open /app/Http/Middleware/Authenticate.php,
you will find public function handle:
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if ($this->auth->guest())
{
if ($request->ajax())
{
return response('Unauthorized.', 401);
}
else
{
return redirect()->guest('auth/login');
}
}
return $next($request);
}
and here is where redirection is managed, and you can modify it for your own needs, or you can create custom middleware.
finally - as it is written in documentation - in the controller, which will need to be authenticated, you will add
public function __construct()
{
$this->middleware('auth');
}
You can create a custom middleware if provided ones do not suit your needs.
On laravel 5.2 if you want to hide the registration form or the login form views you should use your middleware as:
$this->middleware('mymiddleware', ['only' => ['register', 'showRegistrationForm', 'login', 'showLoginForm']]);
OR
$this->middleware('mymiddleware', ['except' => ['register', 'showRegistrationForm', 'login', 'showLoginForm']]);
That is because the register and login routes are the post methods on the AuthController while showXxxxForm are the form views.
Hope it helps anyone.
In Laravel, Middleware is used make to some Routes are access only to the User when User is login, Otherwise it will redirect to the Login Page.
Auth::routes();
Route::middleware(['auth'])->group(function () {
//After Login the routes are accept by the loginUsers...
}
Route::middleware(['admin'])->group(function(){
//the Admin is logged in to access the Routes...
}
//login authentication using middleware
1) make middleware:
php artisan make:middleware adminAuth
2) write in middleware file:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class loginAuth
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
$isAuthenticatedAdmin = (Auth::check());
//This will be excecuted if the new authentication fails.
if (!$isAuthenticatedAdmin){
return redirect()->route('login')->with('message', 'Authentication Error.');
}
return $next($request);
}
}
3) add app/http/kernal.php inside below line
protected $routeMiddleware = [
'adminAuth' => \App\Http\Middleware\AdminAuth::class //Registering New Middleware
];
4)add routes in middleware:
Route::get('login',[AuthController::class,'index'])->name('login'); //named route
Route::get('dashboard',function(){
return view('admin-page.dashboard');
})->middleware("adminAuth");
I have created two middleware in order to protect user route and admin routes
my UserMiddleware looks like this
<?php
namespace App\Http\Middleware;
use Auth;
use Closure;
class UserMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (Auth::user()->hasRole('user')) {
return $next($request);
}
throw new \Exception("Unauthorized");
}
}
and this is my Adminmiddleware
<?php
namespace App\Http\Middleware;
use Auth;
use Closure;
use App\Role;
class AdminMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (Auth::user()->hasRole('admin')) {
return $next($request);
}
throw new \Exception("Unauthorized");
}
}
Now what i want is when admin is logging in, i want a admin dashboard to open and when user is logging in, i want user dashboard to open, but now, it is redirecting me only to the admin route only when I try to login from user and admin, I have my user protected routes like this
Route::group(['middleware' => 'auth', 'user'], function () {
//all user routes
});
and admin protected routes
Route::group(['middleware' => 'auth', 'admin'], function () {
//all admin routes
});
and in my kernel.php, I have also added
'admin' => \App\Http\Middleware\AdminMiddleware::class,
'user' => \App\Http\Middleware\UserMiddleware::class,
and this is how I have validated a login in my controller
$loginData = array(
'email' => Input::get('email'),
'password' => Input::get('password'),
'confirmed' => 1
);
/*
* Checking against the record in database whether the email and password is valid
* Or the record exists in the database
*/
if (Auth::validate($loginData)) {
if (Auth::attempt($loginData)) {
return Redirect::intended('dashboard');
}
}
else {
// if any error send back with message.
Session::flash('error', 'Invalid Email/Password Combination');
return Redirect::to('login');
}
how can I make my middleware work and show admin dashboard when admin logs and user dashboard when user logs in. This has created a big problem for me.
First of all, if you want to show unauthorized users the login form, your middleware should redirect to login form. In order to have it, replace
throw new \Exception("Unauthorized");
with
return redirect(route('login'));
Secondly, your login controller should redirect users to the dashboard corresponding to their roles. In order to get the proper redirect, replace
if (Auth::attempt($loginData)) {
return Redirect::intended('dashboard');
}
with
if (Auth::attempt($loginData)) {
return Redirect::intended(Auth::user()->hasRole('admin') ? 'admin_dashboard' : 'user_dashboard');
}
The last issue is that you apply middleware to your routes incorrectly. If you want to apply multiple middlewares, you need to pass a list as middleware paramter. Replace
['middleware' => 'auth', 'user']
with
['middleware' => ['auth', 'user']]