Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

mstnorris's avatar

Check if route exists

Based on my previous question, I have now set up another Middleware check to see if the User doesn't have Admin privileges. Aptly named User.

The issue is now, that if you are an Admin (Admin Middleware) you are no longer able to see any of the User (non-Admin) routes.

The good thing is that most (if not all) of the standard User routes have admin_ prefixed equivalents, so, my question is, if an Admin tries to visit let's say /modules instead of being redirected to just /admin (because of the Admin middleware), they are redirected to /admin/modules (because it does exist).

If the route doesn't exist, then they are just redirected to the usual /admin route.

0 likes
6 replies
thomaskim's avatar
Level 41

I'm not sure if these are the best ways, but I can think of 2 ways right now. The first would be to use route names. I put all my admin routes inside a route group so their route names all are prefixed with 'admin.' so if you do something similar, you can then do something like this:

public function handle($request, Closure $next)
{
    $routeName = Route::currentRouteName();
    
    // isAdminName would be a quick check. For example,
    // you can check if the string starts with 'admin.'
    if ($this->isAdminName($routeName))
    {
        // If so, he's already accessing an admin path,
        // Just send him on his merry way.
        return $next($request);
    }

    // Otherwise, get the admin route name based on the current route name.
    $adminRouteName = 'admin.' . $routeName;

    // If that route exists, redirect him there.
    if (Route::has($adminRouteName))
    {
        return redirect()->route($adminRouteName);
    }

    // Otherwise, redirect him to the admin home page.
    return redirect('/admin');
}

The second method would be to work directly with the route uri.

public function handle($request, Closure $next)
{
    $uri = $request->path();

    // isAdminUri would be a quick check to see
    // if the route starts with 'admin'
    if ($this->isAdminUri($uri))
    {
        // If he's already accessing an admin path,
        // Just send him on his merry way.
        return $next($request);
    }

    // Create a new request for the admin path
    $adminUri = 'admin/' . $uri;
    $adminRequest = $request->create($adminUri);

    // Get route collection
    $routes = Route::getRoutes();

    try {
        // If we find a match, take the user there.
        $routes->match($adminRequest);
        return redirect($adminUri);
    }
    catch (\Symfony\Component\HttpKernel\Exception\NotFoundHttpException $e) {
        // Otherwise, we didn't find a match so take the user to the admin page.
        return redirect('/admin');
    }
}
mstnorris's avatar

@thomaskim would you give me an example of what $this->isAdminName($routeName) and $this->isAdminUri($uri) would look like?

1 like
thomaskim's avatar

@mstnorris I was thinking of something simple. For example, since all my route names for the admin panel starts with "admin." (ex: "admin.posts.index", "admin.posts.create"), you could do something like this:

private function isAdminName($routeName)
{
    $adminNamePrefix = 'admin.'; // Change this to match your route name prefix.

    return substr( $routeName, 0, strlen($adminNamePrefix) ) === $adminNamePrefix;
}

Same concept for the uri check. Since all routes start with "admin/posts/create", I know that the uri should start with "admin/".

private function isAdminUri($uri)
{
    $adminUriPrefix = 'admin/'; // Change this to match your uri prefix.

    return substr( $uri, 0, strlen($adminUriPrefix) ) === $adminUriPrefix;
}
RachidLaasri's avatar

For the user is the best choice.

public function isAdminName($routeName)
{
    return strpos($routeName, 'admin_');
}
mstnorris's avatar

@thomaskim thank you, that solved it perfectly as far as I can tell. Just what I was looking for. Thanks for adding the other method too, luckily all my routes have very readable names following a convention and the only difference was that the admin routes had a prefix of admin_ so didn't have to modify your code all that much.

@RachidLaasri thanks, I guessed it was better in the User middleware so that's where I put it and it works.

Thank you.

Please or to participate in this conversation.