I have a fresh installation of Laravel Sanctum API. When I try to log a user in after registration or when submitting the registration form twice, I get an exception with the message "The route dashboard could not be found". I don't understand why it's trying to redirect the user to the 'dashboard' route. The only place that I can see 'dashboard' in my project is in RouteServiceProvider.This seems like a bug too me with Sanctum.
this error shows when you try to register while you are already logged, so make sure to log out before register
You are right, App\Providers\RouteServiceProvider\RouteServiceProvider::HOME
const is set to "/dashboard". If you follow the usage of this const you can see that is used by App\Http\Middleware\RedirectIfAuthenticated
middleware
class RedirectIfAuthenticated {
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next, string ...$guards): Response
{
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
return redirect(RouteServiceProvider::HOME);
}
}
return $next($request);
}
}
This middleware is aliased as "guest" in the App\Http\Kernel
:
protected $middlewareAliases = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \App\Http\Middleware\EnsureEmailIsVerified::class,
];
And this middleware is used in unauthenticated routes defined by routes/auth.php
Route::post('/register', [RegisteredUserController::class, 'store'])
->middleware('guest')
->name('register');
Route::post('/login', [AuthenticatedSessionController::class, 'store'])
->middleware('guest')
->name('login');
Route::post('/forgot-password', [PasswordResetLinkController::class, 'store'])
->middleware('guest')
->name('password.email');
Route::post('/reset-password', [NewPasswordController::class, 'store'])
->middleware('guest')
->name('password.store');
This built-in middleware middleware will try and redirect you to the HOME if you are already authenticated.
I think that there is an issue in Laravel breeze scaffolding (php artisan breeze:install api) that not provide a check on the response type in the
App\Http\Middleware\RedirectIfAuthenticated
middleware.
If you see instead the App\Http\Middleware\Authenticate
middleware here is automatically provided a redirectTo
method that check for the expected response ($request->expectsJson()
):
class Authenticate extends Middleware
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*/
protected function redirectTo(Request $request): ?string
{
return $request->expectsJson() ? null : route('login');
}
}
TLDR
In short to work correctly with the App\Http\Middleware\RedirectIfAuthenticated
middleware in API based authentication you can add manually the following check in the middleware:
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
if ($request->expectsJson()) {
return response()->json(['error' => 'Already authenticated.'], 200);
}
return redirect(RouteServiceProvider::HOME);
}
}
return response()->json(['message' => 'authenticated.'], 200);
(because it is not an error, it is the expected behavior) –
Mehta this error shows when you try to register while you are already logged, so make sure to log out before register
To add to highest voted answer:
Even in Laravel 11, the RedirectIfAuthenticated middleware is still not supporting the API setup (it will always try to redirect you instead of returning a JSON response).
This is strange, because the other scenario, where you are not authenticated and trying to reach an authenticated resource, you are getting the correct 'Unauthenticated.' message for a long time now. No idea why they don't add support for this.
Solution:
Override the 'guest' alias with your own middleware in bootstrap/app.php:
->withMiddleware(function (Middleware $middleware) {
$middleware->statefulApi();
$middleware->api(prepend: [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
]);
// Overriding the 'guest' alias because Laravel's RedirectIfAuthenticated
// middleware does not have API support
// https://github.com/laravel/laravel/pull/6229
$middleware->alias([
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
]);
//
})
The middleware:
use Closure;
use Illuminate\Http\Request;
use App\Responses\StandardJsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Auth\Middleware\RedirectIfAuthenticated as BaseRedirectIfAuthenticated;
class RedirectIfAuthenticated extends BaseRedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Closure(Request): (Response) $next
*/
public function handle(Request $request, Closure $next, string ...$guards): Response
{
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (auth()->guard($guard)->check()) {
if ($request->expectsJson()) {
return StandardJsonResponse::error('Unauthorized.', 403);
} else {
return redirect($this->redirectTo($request));
}
}
}
return $next($request);
}
}
Make sure the dashboard route is added to the routes/web.php or routes/api.php file.
ex: Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
Add the "Accept" header to your API request and set the value to "application/json" and it will work.
© 2022 - 2025 — McMap. All rights reserved.
guest
middleware will try to redirect toHOME
that is defined in theRouteServiceProvider
by default ... is the constant forHOME
set todashboard
? – DumuziHOME
is set todashboard
. That's what I don't understand, why it's trying to redirect, it's supposed to return an API response. – Valleeaccept
header for JSON? – Dumuziphp artisan route:list
? – Clareclarence/dashboard
view, you will get the 404 error. But, what if I don't have such endpoint defined or my App doesn't need it? So, forcing to redirect the user to/dashboard
after authenticating is a mistake. It should be/
only. – Rector