Laravel middleware login redirect - laravel

how to create middleware redirect about role. I have 2 middleware, first Admin, next User. Need redirect after login, if role Admin, example redirect to /admin, if User redirect to /user.
Admin middleware:
if(Auth::check() && Auth::user()->isRole() == "Admin"){
return $next($request);
}
return redirect('login');
User middleware:
if(Auth::check() && Auth::user()->isRole() == "User"){
return $next($request);
}
return redirect('login');
WEB routes
Route::group(['middleware' => ['auth']], function () {
Route::get('/', 'DashboardController#index');
Route::group(['middleware' => ['auth' => 'admin']], function (){
Route::resource('/admin', 'AdminController');
});
Route::group(['middleware' => ['auth' => 'user']], function (){
Route::resource('/user', 'AdminController');
});
});

You can make your admin/user middleware to inherit laravel's Authenticate middleware: Illuminate\Auth\Middleware\Authenticate, then have their definitions as below.
Admin Middleware-
public function handle($request, Closure $next, ...$guards)
// Ensure auth - this will automagically re-direct if not authed.
$this->authenticate($request, $guards);
if(Auth::user()->isRole() == "Admin")
return $next($request);
return redirect('/user-default-page')
}
// You can define this for your un-authenticated redirects
protected function redirectTo($request)
{
return '/login';
}
User middleware will then be:-
public function handle($request, Closure $next, ...$guards)
// Ensure auth - this will automagically re-direct if not authed.
$this->authenticate($request, $guards);
if(Auth::user()->isRole() == "User")
return $next($request);
return redirect('/admin-default-page')
}
// You can define this for your un-authenticated redirects
protected function redirectTo($request)
{
return '/login';
}
For routes:
Route::group(['middleware' => 'admin'], function () {
// Put here admin routes, e.g
Route::resource('/admin', 'AdminController');
}
Route::group(['middleware' => 'user'], function () {
// Put here user routes, e.g
Route::resource('/users', 'UserController');
}
// You can still use the default auth routes, say for routes that (somehow), both admin and user can access
Route::group(['middleware' => 'auth'], function () {
Route::resource('/dashboard', 'DashboardController');
}

// Admin Middleware
public function handle($request, Closure $next)
{
if(Auth::check() && Auth::user()->role->id == 1)
{
return $next($request);
}else {
return redirect()->route('login');
}
}
// User Middleware
public function handle($request, Closure $next)
{
if(Auth::check() && Auth::user()->role->id == 2 )
{
return $next($request);
}else {
return redirect()->route('login');
}
}
// Admin Route Group
Route::group(['as'=>'admin.','prefix'=>'admin','namespace'=>'Admin','middleware'=>['auth','admin']], function (){
Route::get('dashboard','DashboardController#index')->name('dashboard');
})
// User Middleware
Route::group(['as'=>'user.','prefix'=>'user','namespace'=>'Author','middleware'=>['auth','user']], function (){
Route::get('dashboard','DashboardController#index')->name('dashboard');
});

Related

Laravel Protected Route With same Model

I changed the users table and put a field called "role" and was wondering if it is possible to use middleware to protect routes only by checking this field.
The table users:
I wnated something like this:
If user role == 0
Route::group(['middleware' => 'auth'], function () {});
If user role == 1
Route::group(['middleware' => 'auth:customers'], function () {});
However with the same table
Make a new middleware:
php artisan make:middleware CustomerMiddleware
The function handle in the new middleware:
public function handle($request, Closure $next)
{
if(Auth::check()){
if($request->user()->role != 0){
return redirect('/');
}
}
return $next($request);
}
The protected route in app/Http/Kernel.php
'CustomerMiddleware' => \App\Http\Middleware\CustomerMiddleware::class,
The group routes:
Route::group(['middleware' => 'CustomerMiddleware'], function () { });

err_too_many_redirects and This page isn’t working in laravel my middleware

i have two users who i have two role normal user and debtor user. i want what to prevent the debtor user from accessing normal user dashboard . i have created debtors dashboard too.below is what i have tried.how can i archive this.
this is my web.php
////// User debtors Authentications ///////////
Route::middleware(['debtors'])->group(function(){//debtors routes will goes here
Route::get('/debtors/home', 'HomeController#kfsdebtors_form');
Route::get('/debtors/kfsdebtors_form', 'HomeController#defaultersdashboard');
Route::get('/debtors/applications_dashboard', 'HomeController#applications_dashboard');
Route::get('/debtors/manage_debt', 'HomeController#manage_debt');
Route::post('/debtors/manage_debt', 'HomeController#transaction');
Route::get('/debtors/manage_debt', 'HomeController#defaulters');
Route::get('/debtors/view_transaction', 'HomeController#view_transaction');
Route::post('/debtors/view_transaction', 'HomeController#view_transaction');
// Route::get('/user/{data}', 'UserController#getData');
// Route::post('/user/{data}', 'UserController#postData');
});
// Route::group(['middleware' => 'debtors'], function () {
// Route::get('/debtors/home/kfsdebtors_form', 'HomeController#kfsdebtors_form');
// Route::get('/debtors/applications_dashboard', 'HomeController#applications_dashboard');
// Route::get('/debtors/manage_debt', 'HomeController#manage_debt');
// });
////// User normal user Authentications ///////////
Route::middleware(['normal_user'])->group(function(){
Route::get('/home', 'HomeController#index');
Route::get('/home', 'HomeController#balance');
});
// Route::group(['middleware' => 'is.admin'], function () {
// Route::get('/user/{data}', 'UserController#getData');
// Route::post('/user/{data}', 'UserController#postData');
// });
Route::get('/register_sawmill', 'Auth\register_sawmill#create')->name('register_sawmill');
Route::post('/register_sawmill', 'Auth\register_sawmill#register');
Route::get('logout', 'Auth\LoginController#logout', function () {
this is my middleware for debtors.php
public function handle($request, Closure $next)
{
if (Auth::user()->debtor == 1)
{
return $next($request);
}
return redirect()->guest('/debtors/home');
}
}
this is normal_user.php middleware
public function handle($request, Closure $next)
{
// if(Auth::check()) {
// if(Auth::user()->debtor == 0) {
// return $next($request);
// }
// }
// return redirect('/home');
// if(!Auth::check() || Auth::user()->debtor != '0'){
// return redirect()->route('/debtors/home');
// }
// return $next($request);
if(Auth::check()) {
if(Auth::user()->debtor == 0) {
return $next($request);
}
}
return redirect('/debtor/home');
}
```
I think you should change return redirect('/home');
and redirect to a simple page, like return redirect('/register_sawmill');
the problem I think, is that the normal user middleware check if the user is authenticated, if not, it should redirect to some page that is not maintained by the middleware

Group Access to pages in laravel

Inside an AuthServiceProvider Access Control is defined. I need to check permission to access page in the routes web.php.
If user is not admin then page should redirect error page or page not found .
How to create a middleware that redirect to 404 page if somebody tries to access the page from the url.
AuthServiceProvider
Gate::define('isAdmin',function($user){
return $user->type === 'admin';
});
Gate::define('isGeneralUser',function($user){
return $user->type === 'user';
});
Gate::define('isPaidUser',function($user){
return $user->type === 'paid';
});
Route web.php
if (Gate::allows('isAdmin') && Gate::allows('isPaidUser')) {
Route::get('/home-page', function () {
return view('pages.trades');
});
}
create middleware
class CheckIsTradeable
{
public function handle($request, Closure $next)
{
if ($request->user()->type !== 'admin' && $request->user()->type !== 'paid') {
abort(404);
}
return $next($request);
}
}
Register inside Kernal
protected $routeMiddleware = [
...
'isTradeable' => \App\Http\Middleware\CheckIsTradeable::class,
];
and check it in your route
Route::get('/home-page', function () {
return view('pages.trades');
})->middleware('isTradeable');

Laravel 5.2 session cookie driver

I have a problem with the cookie session driver. I need to create an app that works with only cookies. With my configuration, the session is not persisting in Laravel 5.2 with the cookie driver. If I use the file session driver, it works.
.env file:
SESSION_DRIVER=cookie
I also created a middleware that checks if a custom session value exists (only handle() function):
public function handle($request, Closure $next)
{
//dd(session('auth')) // null
if (!session('auth')) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
return redirect('/');
}
}
return $next($request);
}
I added the middleware to the $routeMiddleware array in app/Http/Kernel.php:
'cookies' => \App\Http\Middleware\CheckCookies::class,
My routes are:
Route::group(['middleware' => ['web']], function () {
Route::get('/', 'LoginController#index');
Route::post('login', 'LoginController#login');
Route::group(['middleware' => 'cookies'], function () {
Route::get('home','HomeController#index');
Route::get('logout','HomeController#logout');
});
});
Here's my LoginController#login method:
public function login()
{
session([
'auth' => ['name' => 'John Doe']
]);
return redirect('/home');
}
How can I fix this?
Just use Cookie Facades in laravel.
Cookie::queue('key', 'value', $minutes);
To make cookie forever
Cookie::forever('key', 'value');
Modify your code and try this.
LoginController#login
public function login(){
$cookieValue=json_encode(array('name'=>'John Dow'));
Cookie::queue('auth', $cookieValue, 60);
return redirect('/home');
}
CheckCookies Middleware
public function handle($request, Closure $next){
if (!Cookie::get('auth'))
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
return redirect('/');
}
return $next($request);
}
}

working with laravel nested route group

I am using middleware for route groups and have three middlewares admin, teacher, and teacheradmin
Well admin is working fine but suppose I have 10 routes and all of them defined under group teacheradmin (working case for now)
but I want only 5 of those 10 routes to be accessed by middleware teacher and all 10 to be accessed by middleware teacheradmin
this is how I nested route groups
Route::group(['middleware' => 'teacheradmin'], function() {
//defined 5 routes only accessible by teacheradmin
Route::group(['middleware' => 'teacher'], function() {
//defined the other routes accessible by both teacher and teacheradmin
});
});
but the above nesting is not working, teacheradmin is not able to access the routes defined under teacher
plz I need a direction on how can I make it work
Update:
as per the answer I have defined middleware array for common routes
Route::group(['middleware' => ['teacher', 'teacheradmin']], function() {
//defined common routes
});
and the handle methods for teh two middleware is:
teacher
public function handle($request, Closure $next)
{
if(Auth::check())
{
if(Auth::user()->user_type != 'TEACHER')
{
return redirect()->route('dashboard');
}
return $next($request);
}
else
{
return redirect('/')
->withErrors('That username/password does not match, please try again !!!.');
}
}
teacheradmin
public function handle($request, Closure $next)
{
if(Auth::check())
{
if(Auth::user()->user_type != 'TEACHER_ADMIN')
{
return redirect()->route('dashboard');
}
return $next($request);
}
else
{
return redirect('/')
->withErrors('That username/password does not match, please try again !!!.');
}
}
and the dashboard route goes to this method
public function Dashboard(Request $request)
{
$user = Auth::user();
if($user->user_type === 'ADMIN') {
return redirect()->route('dashboardadmin');
} else if($user->user_type === 'TEACHER_ADMIN') {
return redirect()->route('dashboardteacher');
} else if($user->user_type === 'TEACHER') {
return redirect()->route('world_selection');
} else {
return redirect()->route('dashboardchild');
}
}
now the problem I am facing is when I am on dashboard and I try to access a common route as teacheradmin then it also goes to handle of teacher hence coming back to the same page again
Not sure why you are nesting them. You can attach multiple middleware via array notation to a group like this:
Route::group(['middleware' => 'teacheradmin'], function() {
//defined 5 routes only accessible by teacheradmin
});
Route::group(['middleware' => ['teacher', 'teacheradmin']], function() {
//defined the other routes accessible by both teacher and teacheradmin
});
Update:
I think what you are trying to do can be done by using just one middleware with middleware parameters:
Route::group(['middleware' => 'role:teacheradmin'], function() {
//defined 5 routes only accessible by teacheradmin
});
Route::group(['middleware' => 'role:teacher,teacheradmin'], function() {
//defined the other routes accessible by both teacher and teacheradmin
});
And in the role middleware:
public function handle($request, Closure $next, ...$roles)
{
dd($roles);
//Do your role checking here
return $next($request);
}
Disclaimer: ...$roles works from php 5.6 upwards.
As of Laravel 8 I would write it like:
Route::group(
['prefix' => 'v1', 'namespace' => 'Api'],
function(Router $router){
Route::get('/', function(){
return "Did you forget where you placed your keys??";
});
Route::post('/login', [LoginController::class, 'login']); //public
Route::get('/register', [LoginController::class, 'register']); //public
Route::group( //protected routes group
['middleware' => ['auth:sanctum']], //protected via some middleware
function () {
Route::get('/users', [UsersController::class, 'users']);
}
);
}
);

Resources