'Laravel 5.5 change unauthenticated login redirect url
In Laravel < 5.5
I could change this file app/Exceptions/Handler
to change the unauthenticated user redirect url:
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
return redirect()->guest(route('login'));
}
But in Laravel 5.5
this has been moved to this location vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php
so how can I change it now? I don't want to change stuff in the vendor directory encase it gets overridden by composer updates.
protected function unauthenticated($request, AuthenticationException $exception)
{
return $request->expectsJson()
? response()->json(['message' => 'Unauthenticated.'], 401)
: redirect()->guest(route('login'));
}
Solution 1:[1]
But in Laravel 5.5 this has been moved to this location vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php so how can I change it now? I don't want to change stuff in the vendor directory encase it gets overridden by composer updates.
It's just the case that the function is not there by default anymore.
You can just override it as you did in 5.4. Just make sure to include
use Exception;
use Request;
use Illuminate\Auth\AuthenticationException;
use Response;
in the Handler file.
For Example my app/Exceptions/Handler.php
looks somewhat like this:
<?php
namespace App\Exceptions;
use Exception;
use Request;
use Illuminate\Auth\AuthenticationException;
use Response;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
(...) // The dfault file content
/**
* Convert an authentication exception into a response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Auth\AuthenticationException $exception
* @return \Illuminate\Http\Response
*/
protected function unauthenticated($request, AuthenticationException $exception)
{
return $request->expectsJson()
? response()->json(['message' => 'Unauthenticated.'], 401)
: redirect()->guest(route('authentication.index'));
}
}
Solution 2:[2]
Here's how I solved it. In render function I caught exception class. And in case if it's Authentication exception class I wrote my code for redirect (the code I would write in unauthenticated function in previous version).
public function render($request, Exception $exception)
{
$class = get_class($exception);
switch($class) {
case 'Illuminate\Auth\AuthenticationException':
$guard = array_get($exception->guards(), 0);
switch ($guard) {
case 'admin':
$login = 'admin.login';
break;
default:
$login = 'login';
break;
}
return redirect()->route($login);
}
return parent::render($request, $exception);
}
Solution 3:[3]
But in Laravel 5.5 this has been moved to this location vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php so how can I change it now? I don't want to change stuff in the vendor directory encase it gets overridden by composer updates.
We need to just include the use Illuminate\Auth\AuthenticationException;
and then it works as in laravel 5.4
Solution 4:[4]
For Laravel ( 5.4, 6, 7, 8.x )
I don't want to change in the vendor directory encase it gets overridden by composer updates. You can just override it as you did in 5.4. Just make sure to include.
File: App\Exceptions\Handler.php
Copy this below code
and past to your app\Exception\Handler
<?php
namespace App\Exceptions;
use Request;
use Illuminate\Auth\AuthenticationException;
use Response;
use Illuminate\Support\Arr;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];
/**
* Report or log an exception.
*
* @param \Throwable $exception
* @return void
*
* @throws \Exception
*/
public function report(Throwable $exception)
{
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Throwable $exception
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws \Throwable
*/
public function render($request, Throwable $exception)
{
return parent::render($request, $exception);
}
protected function unauthenticated($request, AuthenticationException $exception)
{
// return $request->expectsJson()
// ? response()->json(['message' => $exception->getMessage()], 401)
// : redirect()->guest(route('login'));
if($request->expectsJson()) {
return response()->json(['message' => $exception->getMessage()],401);
}
$guard = Arr::get($exception->guards(), 0);
switch ($guard) {
case 'admin':
$login = 'admin.login';
break;
case 'vendor':
$login = 'vendor.login';
break;
default:
$login = 'login';
break;
}
return redirect()->guest(route($login));
}
}
Solution 5:[5]
The standard exception handler uses a named route.
So, you just define your route to use that name.
So, in your routes/web.php
file, just add the line:
Route::get('mylogin', 'MyLoginController@showLoginForm')->name('login');
The name('login')
bit gives this route a name, so the unauthenticated exception will use this route.
You don't need to bother messing around making your own exception handler, or modifying the standard exception handler.
The named routes used by the boilerplate 'auth' code can be found in the vendor/laravel/framework/src/Illuminate/Routing/Router.php
file, in the auth()
function. (login, logout, register, password.request, password.email and password.reset). These routes are added when you use the Route::auth();
line in the route file.
Solution 6:[6]
In newer versions of Laravel, you should go to
app/Http/Middleware/Authenticate.php
Now you can edit the function and redirect it to wherever you want:
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return route('login');
}
}
Hope it helps.
Solution 7:[7]
Just add a route for login in routes file:
Route::get('/login', [
'uses' => 'UserController@getSignin',
'as' => 'login'
]);
Solution 8:[8]
Replace Your app\Exceptions\Handler.php code with the following....
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];
/**
* Report or log an exception.`enter code here`
*
* @param \Exception $exception
* @return void
*/
public function report(Exception $exception)
{
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
return parent::render($request, $exception);
}
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['message' => $exception->getMessage()], 401);
}
$guard = array_get($exception->guards(),0);
switch ($guard) {
case 'admin':
$login = 'admin.login';
break;
default:
$login = 'login';
break;
}
return redirect()->guest(route($login));
}
}
Solution 9:[9]
Copy this to your app\Exception\Handler
use Request;
use Illuminate\Auth\AuthenticationException;
use Response;
protected function unauthenticated($request, AuthenticationException $exception){
if ($request->expectsJson()) {
return response()->json(['message' => $exception->getMessage()], 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;
}
}
Solution 10:[10]
For Laravel 7.x+
===========**top add class:**================
use Illuminate\Auth\AuthenticationException;
use Illuminate\Support\Arr;
=======================================
public function render($request, Throwable $exception)
{
if($exception instanceof AuthenticationException){
$guard = Arr::get($exception->guards(), 0);
switch($guard){
case 'admin':
return redirect(route('admin.login'));
break;
default:
return redirect(route('login'));
break;
}
}
return parent::render($request, $exception);
}
Solution 11:[11]
For Laravel verison 7.*
File: App\Exceptions\Handler.php
use Illuminate\Support\Arr; //Top Class
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
public function render($request, Throwable $exception) {
// for Multi AUth guard
if($exception instanceof AuthenticationException){
$guard = Arr::get($exception->guards(), 0);
switch($guard){
case 'admin':
return redirect(route('admin.login'));
break;
default:
return redirect(route('login'));
break;
}
}
return parent::render($request, $exception);
}
Solution 12:[12]
Other than overriding
, you could directly make changes in Handler.php
to the existing function unauthenticated located at vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php
to redirect to intended route based on guards.
/**
* Convert an authentication exception into a response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Auth\AuthenticationException $exception
* @return \Illuminate\Http\Response
*/
protected function unauthenticated($request, AuthenticationException $exception)
{
$guard = array_get($exception->guards(),0);
switch ($guard) {
case 'admin':
return $request->expectsJson()
? response()->json(['message' => $exception->getMessage()], 401)
: redirect()->guest(route('admin.login'));
break;
default:
return $request->expectsJson()
? response()->json(['message' => $exception->getMessage()], 401)
: redirect()->guest(route('login'));
break;
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow