laravel middleware not working as expected - php

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']]

Related

Laravel - add in core/routes/ if username exist

Route::middleware('admin')->group(function () {
Route::get('dashboard', 'AdminController#dashboard')->name('dashboard');
Route::get('profile', 'AdminController#profile')->name('profile');
Route::post('profile', 'AdminController#profileUpdate')->name('profile.update');
Route::get('password', 'AdminController#password')->name('password');
Route::post('password', 'AdminController#passwordUpdate')->name('password.update');
I have this code in routes and I want to add "if username == "staff"
Route::get('dashboard', 'AdminController#dashboard')->name('dashboard');
not others pages.
First create StaffMiddleware.php in following path app/Http/Middleware/StaffMiddleware.php
<?php
namespace App\Http\Middleware;
use Closure;
class StaffMiddleware
{
/**
* Handle an incoming request. User must be logged in to do admin check
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (\Auth::user()->username == 'staff')
{
return $next($request);
}
return redirect()->guest('/');
}
}
In app/Http/Kernel.php add the following line
protected $routeMiddleware = [
// your existing code
'staff' => \App\Http\Middleware\StaffMiddleware::class,
];
Rewrite the following route
Route::get('dashboard', 'AdminController#dashboard')->name('dashboard');
TO
Route::get('dashboard', 'AdminController#dashboard')->name('dashboard')->middleware('staff');
Now whenever you want to check this condition you just need to add ->middleware('staff') in route.

Laravel redirect based on role - spatie/laravel-permission

I am using this package spatie/laravel-permission and what I want to do is:
super-admin, admin, members have the same login and after logged in it redirect to different routes.
The super-admin and admin have the same redirect. So I put this code.
//app\Http\Controllers\Auth\LoginController.php
protected function authenticated(Request $request, $user)
{
if ( $user->hasAnyRole(['super-admin', 'admin']) ) {// do your margic here
return redirect()->route('admin.dashboard');
}
return redirect('/home');
}
and then this is my routes
//routes/web.php
Auth::routes();
Route::group(['middleware' => ['role:member']], function () {
Route::get('/', 'HomeController#index')->name('home');
});
Route::group(['middleware' => ['role:super-admin|admin'], 'prefix' => 'admin'], function () {
Route::get('/', 'Admin\HomeController#dashboard')->name('admin.dashboard');
});
After login, what I want to do is when a super-admin/admin visit the site.com/* it should redirect to site.com/admin/ cause he is not authorize cause he is not a member and also when a member visit the site.com/admin/*, he redirect to site.com/ cause he is not admin/super-admin, the rest will go to login page when not authenticated.
It displays like this,
It should redirect based on their role homepage instead display 403 error.
Well, based on the package's middleware, there's no redirection logic involved. It is just checking if it has the correct permissions and throwing an unauthorized exception if the user does not.
You would need to write your own custom middleware, where you will check whether the user has the appropriate roles and to redirect to the appropriate url. A very simplistic example would be something like this (in the case of an admin).
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class CheckIfAdmin
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string|null $guard
* #return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if ( $user->hasAnyRole(['super-admin', 'admin']) ) {
return $next($request);
}
return redirect('/');
}
}
You would then attach this middleware instead of the other one.

Laravel 5.5 abort error when trying to authenticate middleware

When i try to login into my dashboard, my authentication works well without middleware, but when i apply middleware and try to login to the dashboard i get this.
Which this is linked to the my authenticate middleware file
Middleware/Authenticate.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class Authenticate
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(! Auth::User()) {
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated. You are not a User.'], 401);
}
abort(403, "You're not a User no permission bro");
}
return $next($request);
}
}
My route is followed by:
Route::get('/auth/signup','UserController#getRegister')->name('getRegister');
Route::post('/auth/signup', 'UserController#userRegister')->name('signup');
Route::post('/auth/signin','UserController#userLogin')->name('user.login');
Route::get('/auth/login', 'UserController#getLogin')->name('login');
Route::get('/', 'UserController#getHome')->name('home');
Route::get('/auth/logout', 'UserController#logOut')->name('logout');
Route::group(['middleware' => 'myauth'], function() {
Route::get('/dashboard', 'UserController#getDashboard')->name('dashboard');
});
Thanks in advance im beginning to think there is a bug because im following the laravel 5.5 practices.

laravel constructor redirect

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');

Using Laravel Auth middleware

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");

Categories