0
votes

I'm building an app in Laravel v5.6 which should be entirely behind a login page (except for the login page itself and password reset pages).

I have written a middleware class CheckAuth - the essentials are,

public function handle($request, Closure $next)
{
    if (auth()->guest() && $this->requestIsNotForGuests($request->path())) {
        return redirect()->route('login');
    }

    return $next($request);
}

If an unauthenticated user requests an unregistered route they see a 404 page. Unauthenticated users shouldn't know whether a route exists or not.

How can I redirect any unauthenticated request (excluding the login page itself and password reset pages) to the login page?

I have tried using route groups with middleware in routes/web.php but this isn't working as expected.


Update...

I have added the following to the end of routes/web.php,

Route::any('{any}', function() {
    abort(404);
})->where('any', '.*');

This achieves the behaviour I'm after but doesn't feel right - is there a better way?

3
Shouldn't the if statement read if (auth()->guest() || $this->isUnauthorisedRequest($request->path()))Derek Pollard
So if the user is a guest OR is unauthorized for the current request path, redirect to login pageDerek Pollard
That will cause an infinite redirect loop. A redirect isn't necessary if a guest requests an allowed route.Steve
then your method named isUnauthorisedRequest should be able to tell that the requested path is authorized for everyone. Either your naming convention here isn't indicative of its functionality or somethings wrongDerek Pollard
OK, I can see how it could be misleading, I've updated the method name to make its functionality clearer.Steve

3 Answers

2
votes

You simply need to wrap all of your routes inside the middleware. It's very common practice. Your middleware dictates the rules and redirects accordingly, either to the route that a user is trying to access if they are authenticated or to a different place/different action if not.

Route::middleware('auth')->group(function() {
    //Routes you want affected here
});

The standard Auth middleware is fine for this, just amend it to what you want to happen if the user isn't authenticated.

Edit

Just some common sense, your login page would be outside of the middleware group 😉

** Edit 2 **

After understanding the question better, you are trying to pass any route, even if it doesn't exist through the auth middleware.

Using all the information I typed above you need to now apply this.

Use the standard auth middleware, you do not need to change anything about the middleware, it will do what you require

Wrap your routes, as suggested inside the middleware group, see what I put above, leave out the login routes!

Now add a new Route like the example below outside of the middleware group, this will be outside with the login rotues

Route::get(/{slug}, 'HomeController@redirector');

I must stress that this Route needs to be the last in your web.php

Now create a method in your HomeController like so:

public function redirector($slug)
{
    return redirect()->route('login');
}
0
votes

Try this:

if (Auth::guest()) {
   return redirect()->route('route_name');
}

without return $next($request); (it cause "continuation" of request).

By the way, you can create new route file and register it inside RouteServiceProvider. And you didn't specified Laravel version...

0
votes

If you just want to show login page instead of 404, you can modify your \App\Exceptions\Handler::render method. Just place

if ($exception instanceof NotFoundHttpException) return redirect('/login');

to the first row of this method. And

use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

of course.

$exception->getCode() === 404 not working for me.