Laravel Auth hidden redirect - php

Install new Laravel 5.4 project.
Run php artisan make:auth.
Go to http://localhost:8000/home (without being logged in).
I get redirected to http://localhost:8000/login
This redirect seems like magic. This is the route for home:
|| GET|HEAD |home||App\Http\Controllers\HomeController#index|web,auth|
We never get to the index() method because the auth middleware takes
over. I open the auth middleware file Illuminate\Auth\Middleware\Authenticate.php and there's no mention of the /login redirect.
Where is the redirect from /home to /login defined?

Check app/Exceptions/Handler.php file and you'll see Exception handler for unauthenticated users:
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
return redirect()->guest(route('login'));
}
P.S. redirect to home you can see in app/Http/Middleware/RedirectIfAuthenticated.php file.
UPD1: redirect to home after login/register you can set in app/Http/Controllers/Auth/LoginController.php and app/Http/Controllers/Auth/RegisterController.php.
It looks like
protected $redirectTo = '/home';

Related

PHPUnit assertion for authenticated user in Laravel when redirecting from another page

I have redirected the root / to the /login page as I don't have a root page. I want to make a PHPUnit test pass when a user is authenticated and visit the root / page and the assertion should go the /login and then /home path but I can't make it work.
web.php
Route::get('/', function () {
return redirect()->route('login');
});
ExampleTest.php
public function testRedirectShouldBeOnTheHomeWhenLoggedIn()
{
$user = factory(User::class)->make();
$response = $this->actingAs($user)->get('/');
$this->assertAuthenticated();
$response->assertStatus(302);
$response->assertRedirect('login');
$response->assertRedirect('home');
}
The relevant test fails on the $response->assertRedirect('home'); even though a user is authenticated. So, the login page should automatically redirect to the /home. Not sure what am I missing.

Retain route for respective guard logins after logout via address bar

I've got multiple guards. All are working fine.
However if a role log out (unauthenticated) from the app and I want to access any e.g /admin/* except admin/login page via address bar, it doesn't redirecting and retain the /admin/login route. it's redirecting to /login instead. It applies to other roles too. How do I do to retain it?
If you are using the default built-in \Illuminate\Auth\Middleware\Authenticate middleware to handle authentication then that will throw an AuthenticationException along with the guards that were checked. You can handle the exception differently by overriding the unauthenticated in your exception handler:
App/Exceptions/Handler.php
class Handler extends ExceptionHandler {
//...Other code
protected function unauthenticated($request, AuthenticationException $exception) {
if (in_array('admin', $exception->guards()) && !$request->expectsJson()) {
return Redirect::guest('/admin/login');
}
return parent::unauthenticated($request, $exception);
}
corrected by OP

Change default login URL

I am trying to change default login URL redirection when unauthenticated use tries to access a page. Basically it redirects to /login but I want it to '/'
I am using the default laravel Auth which is created by php artisan make:auth. I just want to redirect to other URL when it's unauthenticated user.
Note: I'm at Laravel 5.6
With default auth scaffolding Laravel will redirect to a route named login.
Option 1
Put this in your app/Exceptions/Handler.php:
use Illuminate\Auth\AuthenticationException;
// ... Other stuff
protected function unauthenticated($request, AuthenticationException $exception)
{
return $request->expectsJson()
? response()->json(['message' => $exception->getMessage()], 401)
: redirect()->guest('/');
}
Put your desired url in redirect()->guest('/');
Option 2
Rename the route you want to redirect to to login:
Auth::routes();
Route::get('/', function () {
return 'login';
})->name('login');
And change the form action from route('login') to /login in resources/views/auth/login.blade.php:
<form method="POST" action="/login">

Laravel automaticly redirect on authentication exception

im working with laravel 5.5 and tried to protect an api route. I assigned the 'auth' middleware to this route, but when i tested it, i get an InvalidArgumentException aka 'Route [login] is not defined'. Im not reffering to this route in any way, laravel automaticaly tried to redirect to this route. I found the following code line in file 'laravel\framework\src\Illuminate\Foundation\Exceptions\Handler.php':
/*
* 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' => $exception->getMessage()], 401)
: redirect()->guest(route('login'));
}
So im wondering, whats the best way to catch this exception globally on every route?
From my understanding, its because you added an auth middleware to the route. So whenever the route is accessed without an authentication, the route is redirected to the name login route which is the login page by default.
You can add an unauthenticated method to your app/Exceptions/Handler.php with the following code. So if the request is in API or expecting JSON response, it will give a 401 status code with JSON response. If the route is accessed using web routes, it will be redirected to the default page. In the below example, am redirecting it to a login page.
Note: This method existed in the app/Exceptions/Handler.php till laravel 5.4.
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
return redirect()->guest(('login'));
}
Don't forget to import use Illuminate\Auth\AuthenticationException;
Edit: Explanation for the error Route [login] is not defined. This is because laravel is trying to redirect to a named route. This named route is available if you are using the laravel auth scaffolding. If you are manually creating the functions, even if the route login exists, it should be named as login. For more information, see https://laravel.com/docs/5.5/routing#named-routes

customize redirection logged in user on /login route - laravel

I have a laravel application
login page is in route /login
there is a logged in user and clicks on a login button (or basically open URL /login)
application redirects the user to /home but I want to be redirected to /dashboard
I changed the redirect fields in Auth controllers to /dashboard. results when a user signs in, application redirects him to /dashboard
but what about a logged in user?
I use laravel 5.4, thank you for helping
You should use the RedirectIfAuthenticated middleware that is supplied with Laravel located in App\Http\Middleware\RedirectIfAuthenticated.
Then, in the following block, make sure it's set to /dashboard.
if (Auth::guard($guard)->check()) {
return redirect('/dashboard');
}
Then add the middleware to your login route by either wrapping it in a group:
Route::group(['middleware' => 'guest'], function(){
//Auth routes for non-authenticated users
});
Or you can do it on the route directly:
->middleware('guest');
Goto login controller which is located in
app->Http->Auth->LoginController
Set
protected $redirectTo = '/dashboard'
Hope it works.
Source : https://laravel.com/docs/5.4/authentication#included-authenticating
Since you want to redirect logged in user you can override showLoginForm() method in LoginController like this:
public function showLoginForm()
{
if (auth()->check()) {
return redirect('/dashboard');
}
return view('auth.login');
}
But I guess a better way to solve the problem could be just hiding login button or link from logged in users:
#if (auth()->guest())
{{-- Show register and login links --}}
#endif

Categories