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

SigalZ's avatar

Error when using to_route

Laravel 9, using verify email on registration.

What I want to do is when a user's email is not verified and he tries to login, he should be logged out and redirected to the verify-email view.

Reading Laravel 9 documentation and following a tutorial I found, I came up with this:

In my routes/web.php:

Route::group(['middleware' => ['auth']], function() {
    Route::get('/logout/{redirectTo}', [LogoutController::class, 'logout'])->name('logout-user');
});

In the LogoutController:

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;

class LogoutController extends Controller
{    
    
    /**
     * Log the user out of the application.
     *
     *
     */
    public function logout($redirectRoute)
    {        
        Auth::logout();
    
        Session::flush();

        return to_route($redirectRoute);
    }
}

In the LoginController:

 protected $redirectTo = RouteServiceProvider::HOME;
    
    protected function redirectTo()
    {
        if (auth()->user()->hasRole('Customer')) {
            if(auth()->user()->email_verified_at) {
                return $this->redirectTo;
            } else {
                return to_route('logout-user', 'verification.notice');
            }                
        }

        return route('admin');        
    }
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

When trying to login with a user that his email is not verified, I get this error: Header may not contain more than a single header, new line detected

What am I doing wrong?

0 likes
14 replies
Sinnbeck's avatar

What's the output of

    public function logout($redirectRoute)
    {        
         dd($redirectRoute);
        Auth::logout();
    
        Session::flush();

        return to_route($redirectRoute);
    }

I'm unsure why it's part of the url

Snapey's avatar

why not stop them logging in in the first place?

Of course you would need to allow guest access to the verification routes

SigalZ's avatar

@Snapey Yes, I'm sorry for the late reply. I realized that the user needs to be logged in to see the verification route which doesn't make much sense to me.

What is the point of verifying the email if the user can login without the verification?

I'm trying to figure out how do I give a guest access to this route now.

SigalZ's avatar

@Snapey Ok, that's what's happening now.

If I do:

 if (auth()->user()->hasRole('Customer')) {
            if(auth()->user()->hasVerifiedEmail()) {
                return $this->redirectTo;
            } else {                
               //Auth::logout();    
               Session::flush();
               return route('verification.notice');
            }              

It goes to the verify notification but the user is not being logged out.

If I do:

if (auth()->user()->hasRole('Customer')) {
            if(auth()->user()->hasVerifiedEmail()) {
                return $this->redirectTo;
            } else {                
               Auth::logout();    
               Session::flush();
               return route('verification.notice');
            }              

The user is being logged out and it stays on the login page.

I tried adding this to the routes/web file:

Route::get('/email/verify', function () {
    return view('auth.verify');
})->name('verification.notice');

didn't change anything.

I also tried using the middleware 'verified' on a route, it just redirects the user to the login page and says nothing about verifying the email, so the user has no idea why he can't go into a certain page.

So how do I log the user out and redirect them to the verify notification view? Or prevent them from login in?

SigalZ's avatar

I also don't understand how does it all work if I actually disabled all the routes in the web file:

//Registration
/*
Route::get('/email/verify', function () {
    return view('auth.verify');
})->name('verification.notice');

Route::get('/email/verify/{id}/{hash}', function (EmailVerificationRequest $request) {
    $request->fulfill();

    return view('auth.verified');
})->middleware(['auth', 'signed'])->name('verification.verify');

Route::post('/email/verification-notification', function (Request $request) {
    $request->user()->sendEmailVerificationNotification();

    return back()->with('message', 'Verification link sent!');
})->middleware(['auth', 'throttle:6,1'])->name('verification.send');*/

They are all commented out, yet they work when I register. So how does that happen?

Why does the documentation says we need to add these routes, when they exist already?

I mean they are commented out in the web file, yet artisan route:list show these routes.

I'm losing it.

thinkverse's avatar

@SigalZ If you're using Laravel Breeze, Fortify, or Jetstream then email verification is built-in to the package. In Breeze, the email verification is in the auth.php file starting at line 37 if you use the default blade stubs. For Fortify and Jetstream you can find it in Fortify's routes.php file on line 80 as part of Fortify's email verification feature.

thinkverse's avatar

@SigalZ Are you using any auth starter kit that could've added email verification? Laravel UI perhaps? Otherwise, If you have the latest version of Laravel 9 installed you can run php artisan about to see if your routes are cached. If they are you can remove that cache with php artisan route:clear. That might help.

SigalZ's avatar

I think I got very confused with everything. I did install Laravel UI, I guess that's what created all the routes. But, now how do I do what I need to do? Users should not be logged in if their email is not verified.

thinkverse's avatar

@SigalZ Yeah, Laravel UI also comes with email verification if you've enabled it. Shouldn't be active otherwise I don't think, unless they've changed it.

Auth::routes(['verify' => true]);
SigalZ's avatar

@thinkverse I'm not sure you understand my issues. I want to use the email verification, I am using it.

I don't want a user to be able to login if his email is not verified.

I want him to be logged out and redirected to the email verification view named: verification.notice.

thinkverse's avatar

@SigalZ Ok, since you're using Laravel UI you can update your LoginController and check after a user has been authenticated if they're verified and if not, log them out and redirect them. You can do that by adding the following method to your LoginController.

/**
 * The user has been authenticated.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  mixed  $user
 * @return mixed
 */
protected function authenticated(Request $request, $user)
{
    //
}

This method is overwritable and should return a response, or false to keep moving to the default response. You can see how it connects in the AuthenticatesUsers trait.

SigalZ's avatar

@thinkverse Thank you, but I still can't get it to work.

I added this to my LoginController:

protected function authenticated(Request $request, $user)
{
    if(auth()->user()->hasVerifiedEmail()) {
        return $this->redirectTo;
    } else {    
       Auth::logout();            
       return to_route('verification.notice');
    }                
}

It stays on the login page, clears the login form, does not redirect to the verification.notice route.

If I remove the Auth::logout(); it redirects to the verification.notice view, but I want to log the user out.

somewhere it sets this route to be shown only to logged in users and I can't find where to allow it for guests.

thinkverse's avatar

@SigalZ Did some testing and after further investigation, it seems your use-case won't work with Laravel UI unless you implement the email verification yourself. Laravel UI expects the user to be authenticated when they verify their email. You can read more in the VerifiesEmails trait.

Please or to participate in this conversation.