Error in Handler Class - Laravel - php

I am using Laravel 5.5 and trying to implement multi authentication for users and admin. I am getting this error when i try to call admin login form in browser.
Error :
Declaration of App\Exceptions\Handler::unauthenticated($request, App\Exceptions\AuthenticationException $exception) should be compatible with Illuminate\Foundation\Exceptions\Handler::unauthenticated($request, Illuminate\Auth\AuthenticationException $exception)
Here is my unauthenticated function in app/Exceptions/Handler:
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
$guard = array_get($exception->guards(), 0);
switch ($guard) {
case 'admin':
$login = 'admin.login';
break;
default:
$login = 'login';
break;
}
return redirect()->guest(route($login));
}
Please help me to resolve this issue.

You forgot to add use Illuminate\Auth\AuthenticationException at the top of your file

I am using Laravel 7.X
And I prefer to do that in Authenticate middleware
I did it like bellow and It is working well for me.
namespace App\Http\Middleware;
use Closure;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
use Illuminate\Support\Arr;
class Authenticate extends Middleware
{
protected $guards = [];
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string[] ...$guards
* #return mixed
*
* #throws \Illuminate\Auth\AuthenticationException
*/
public function handle($request, Closure $next, ...$guards)
{
$this->guards = $guards;
return parent::handle($request, $next, ...$guards);
}
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* #param \Illuminate\Http\Request $request
* #return string|null
*/
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
if (Arr::first($this->guards) === 'admin') {
return route('admin.login');
}
return route('trainee.login');
}
}
}

Thank you for your recent answer Thanh Nguyen. My custom auth middleware is work with the latest version
if (Arr::first($this->guards) === 'admin') {
return route('admin.login');
}
return route('customer.login');
Previously using unauthenticated function inside Handler.php to replace the parent function.
protected function unauthenticated($request, AuthenticationException $exception)
{
$guard = Arr::get($exception->guards(), 0);
switch ($guard) {
case 'respondent':
$login = 'respondents.login';
break;
case 'admin':
$login = 'admin.login';
break;
default:
$login = 'admin.login';
break;
}
return $request->expectsJson()
? response()->json(['message' => $exception->getMessage()], 401)
: redirect()->guest(route($login));
}
Both is working, but there was likely an issue for latest version on array_get to obtain guards we use:
$guard = array_get($exception->guards(), 0);
For anyone facing this issue, this method has been deprecated for Laravel 7.* and above

Error in Handler Class - Laravel
public function handle($request, Closure $next)
With
public function handle($request, Closure $next, ...$auth)

Related

Laravel 8 | Redirect according to role after login

i am using Laravel as Framework, I'm creating a page with various types of roles, I have the authentication controlled with a middleware, so far so good. My problem is with the redirection after login. I have my users table with a field called "Rol" I need, before entering the system, to verify that "Rol" has my user and according to that, I am redirected to a dashboard or another.
Route::get('/dashboard', [GeneralController::class,'redirectAfterLogin'])->middleware(['auth'])->name('dashboard');
i am using this in the routes. i have un general controller with a function called "redirectAfterLogin"
This is my function
public function redirectAfterLogin(Request $request){
$role = $request->user()->role;
switch ($role) {
case 'Admin':
return redirect(route('admin/dashboard'));
break;
case 'SubAdmin':
return redirect(route('cita/addAppointment'));
break;
case 'Medico':
return redirect(route('cita/pattientsToday'));
break;
case 'Paciente':
return redirect(route('cita/decideLevel'));
break;
default:
# code...
break;
}
}
This works for me, but I don't think it's the right way. I know that with a middleware you can control this, but I don't know how, or what else should change for that middleware to work
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure(\Illuminate\Http\Request):
(\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* #param string|null ...$guards
* #return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next, ...$guards)
{
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
if($request->user()->role == "Admin"){
return "/AdminDashboard";
}else{
return "/GeneralDashboard";
}
}
}
return $next($request);
}
}
This middleware is supposed to handle redirects but no matter how I do it it doesn't happen
Ok, I managed to find the solution. I implemented a predesigned login with Brezze (I think that's how it is written) The point is that to redirect it creates a controller called "AuthenticatedSessionController"
This has the "store" method where the verification of the session data is done and if they are correct it is redirected to "HOME"
This is where we put our logic, in my case I did it with a switch.
class AuthenticatedSessionController extends Controller
{
/**
* Handle an incoming authentication request.
*
* #param \App\Http\Requests\Auth\LoginRequest $request
* #return \Illuminate\Http\RedirectResponse
*/
public function store(LoginRequest $request)
{
$request->authenticate();
$request->session()->regenerate();
$role = $request->user()->role;
switch ($role) {
case 'Admin':
return redirect(route('admin/dashboard'));
break;
case 'SubAdmin':
return redirect(route('cita/addAppointment'));
break;
case 'Medico':
return redirect(route('cita/pattientsToday'));
break;
case 'Paciente':
return redirect(route('cita/decideLevel'));
break;
}
}
Now, there is also a middleware called "RedirectIfAuthenticated", it takes care of the redirects after you are logged in and change the url to the root.
Let me explain, suppose I have 2 users Admin and Public, each one has a different HOME, when logging in who redirects you to the correct HOME, it is the "AuthenticatedSessionController" controller, and if after logging in you write in the URL
"http://My_domain/" (i mean, the root) will be the middleware "RedirectIfAuthenticated" who makes the redirection to the correct HOME. The controller only works when you login, the other times the middleware will do it.
In my middleware i have this.
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure(\Illuminate\Http\Request):
(\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* #param string|null ...$guards
* #return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next, ...$guards)
{
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
$role = $request->user()->role;
switch ($role) {
case 'Admin':
return redirect(route('admin/dashboard'));
break;
case 'SubAdmin':
return redirect(route('cita/addAppointment'));
break;
case 'Medico':
return redirect(route('cita/pattientsToday'));
break;
case 'Paciente':
return redirect(route('cita/decideLevel'));
break;
}
}
}
return $next($request);
}
Both the controller and the middleware are created by Brezze, I don't know how it will work with other login templates. But at least in Brezze I think this would be the correct way to redirect.
Your problem is return string, you need add return redirect(url_name)
Try this code, I think she will help you.
public function handle(Request $request, Closure $next, ...$guards)
{
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
switch (Auth::guard($guard)->user()->role){
// Redirect Admin Dashboard
case 'Admin':
return redirect('/AdminDashboard');
break;
// If need any Roles for example:
case: 'RoleName':
return redirect('url');
break;
default: return redirect('/GeneralDashboard');
}
}
}
return $next($request);
}

Laravel - Redirect authenticated users

In my Laravel application I have a registration system that uses the default scaffolding created via php artisan make:auth to register new users, but after logging in I wanted to take the user to another page called member-type so that they can select what type of member they'd like to be.
I utilitized protected function authenticated(Request $request, $user) which comes from AuthenticatesUsers to check that a user has successfully logged in, I then check whether a member type is set.
The method looks like this:
/**
* The user has been authenticated.
*
* #param \Illuminate\Http\Request $request
* #param mixed $user
* #return mixed
*/
protected function authenticated(Request $request, $user)
{
Log::info("{$user->log_reference} logged in to their account with IP: {$request->getClientIp()}");
if(!$user->investor_type_selected){
// dd('I NOT SELECTED');
return redirect()->route('user.investor-type');
} elseif(!$user->member_type_selected){
dd('M NOT SELECTED');
return redirect()->route('user.member-type');
} else{
dd('BOTH SELECTED');
return redirect()->route('user.dashboard');
}
}
The methods member_type_selected andinvestor_type_selectedcome from myUser` model and they look like this:
/**
* Check whether this user has selected an investor type
*/
public function getInvestorTypeSelectedAttribute()
{
return !empty($this->investor_type) ? true : false;
}
/**
* Check whether this user has selected an investor type
*/
public function getMemberTypeSelectedAttribute()
{
return !empty($this->member_type) ? true : false;
}
Pretty simple stuff.
The dump and die was there to test whether the statements were executing.
Anyway, the issue I have is with the Middleware RedirectIfAuthenticated which looks like this as I'm using a custom guard:
/**
* 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)
{
switch ($guard) {
case 'admin':
if (Auth::guard($guard)->check()) {
return redirect()->route('admin.dashboard');
}
break;
default:
if (Auth::guard($guard)->check()) {
return redirect()->route('user.dashboard');
}
break;
}
return $next($request);
}
Now, as soon as a user is authenticated this kicks in and bypasses my redirects with authenticated. I need this Middleware generally to make sure users get back to their dashboard, but is there a way to prevent this bypassing my redirects?
no need to override authenticated function , try this in your RedirectIfAuthenticated middleware
public function handle($request, Closure $next, $guard = null)
{
switch ($guard) {
case 'admin':
if (Auth::guard($guard)->check()) {
return redirect()->route('admin.dashboard');
}
break;
default:
if (Auth::guard($guard)->check()) {
$user = Auth::guard($guard)->user();
if(!$user->investor_type_selected){
return redirect()->route('user.investor-type');
} elseif(!$user->member_type_selected){
return redirect()->route('user.member-type');
} else{
return redirect()->route('user.dashboard');
}
}
break;
}
return $next($request);
}

How to make 3 level authentication system in laravel?

I have an existing project build with Laravel 5.5. It has a USER login and Admin login. Now I want to add a 3rd authentication AUTHOR login. I have copy pasted admin files in author folder and edited them replacing admin by author . But it's not working even I added author in handle.php and config/auth.
I don't want to use roles.
Here are my codes:
Handler.php
protected function unauthenticated($request, AuthenticationException $exception) {
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
$guard = array_get($exception->guards(),0);
switch ($guard) {
case 'admin':
return redirect()->guest(route('admin.login'));
break;
default:
return redirect()->guest(route('login'));
break;
}
}
protected function unauthenticated($request, AuthenticationException $exception) {
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
$guard = array_get($exception->guards(),0);
switch ($guard) {
case 'author':
return redirect()->guest(route('author.login'));
break;
default:
return redirect()->guest(route('login'));
break;
}
}
Redirectif authenticated
class RedirectIfAuthenticated {
/**
* 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) {
switch ($guard) {
case 'admin':
if (Auth::guard($guard)->check()) {
return redirect('/admin-dashboard');
}
break;
default:
if (Auth::guard($guard)->check()) {
return redirect('/user/dashboard');
}
break;
}
return $next($request);
}

redirecTo() method in laravel not working

I have been trying to redirect a user after login, there are two links that should be redirected to when a certain condition is fulfilled.
protected function redirectTo(){
$userRole = User::findOrFail(Auth::id());
// dd($userRole->roles);
if($userRole->roles == 'admin'){
return 'admin/controlpanel';
}
elseif ($userRole->roles == 'participant') {
return 'student/profile';
}
}
I created this function to redirect but it still redirect to '/home'. Then I read over here and on git that I also had to the modify RedirectIfAuthenticated model in the middleware, I did this
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
use App\User;
class RedirectIfAuthenticated
{
/**
* 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 (Auth::guard($guard)->check()) {
return self::redirectTo();
}
return $next($request);
}
protected function redirectTo(){
$userRole = User::findOrFail(Auth::id());
if($userRole->roles == 'admin'){
return 'admin/controlpanel';
}
if ($userRole->roles == 'participant') {
return 'student/profile';
}
}
}
but is still keeps giving me this error in my previous question
here
I reverted to my previous git commit, then coded step by step till I discovered it was coming from the middleware I modified...
use redirect helper like this: return redirect('admin/controlpanel');

how to exce middleware , when the laravel exception

I use laravel5.5 for a web program. But when the program is exception, the middleware don't work.
what should i do for it?
my middleware code is list:
namespace App\Http\Middleware;
use Closure;
class ApiException
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string|null $guard
* #return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);
$env = config('app.env');
$statusCode = $response->getSatusCode();
if ($statusCode >= 500 && $env != 'dev') {
$response->setContent(['error' => 'Internal Server Error']);
}
return $next($request);
}
}
thank you help me !
There is no way you can do that in Middlewares. You can control exceptions in your app\Exceptions\Handler.php instead.
In middleware can't but in Exception/Handler can..
anytime the exception occurred.. it not entered the middleware, it entered Exception/Handler.php..
in render method
public function render($request, Exception $exception)
{
if ($exception->getCode() >= 500 ||) {
//return redirect()->route(); do something here
}
return parent::render($request, $exception);
}

Categories