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

bi3_dev's avatar

Email Verification not working in production

I have deployed my Laravel Application in Azure and email verification is not working. I am using TALL Stack with Breeze as base. I am using Laravel 10 with Livewire 3.

When new user is created from Livewire Forms, the verification email is sent successfully after user creation. In local environment everything works and email gets verified. But in production I am getting 403 Unauthorized error for the verification URL.

I found some similar issues but every answer was pointing out to the code that was already in Breeze and I am not able to find any solution to my issue.

//  App\Livewire\Forms\UserFrom.php
use App\Notifications\WelcomeUserNotification;
...		
public function create(){
	$newUser = new User();
    $newUser->name = $this->name;
    $newUser->email = $this->email;
	...
	if($newUser->save()){
	    $newUser->notify(new WelcomeUserNotification());
        ...
    }
}

User model is correctly setup

class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable, ... ;
    ...

The custom notification looks like this,

// App\Notifications\WelcomeUserNotification.php
use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Notifications\Messages\MailMessage;
...
class WelcomeUserNotification extends VerifyEmail 
{
	public function toMail($notifiable)
    {
		return (new MailMessage)
            ->greeting('Hello, ' . $notifiable->name . '!')
            ->subject('Please Verify Your Email Address')
            ->line('Your account has been created at ' .
              	config('app.name') . ' on ' .
                $notifiable->created_at->format('M d, Y, g:i A'))
            ->action('Click to Verify Email Address', $this->verificationUrl($notifiable))
            ->line('Thank you for using our application!');
    }

I have not changed anything from Breeze, the auth.php route is untouched

// App\Routes\Auth.php
...
Route::middleware('auth')->group(function () {
    Route::get('verify-email', EmailVerificationPromptController::class)
        ->name('verification.notice');

    Route::get('verify-email/{id}/{hash}', VerifyEmailController::class)
        ->middleware(['signed', 'throttle:6,1'])
        ->name('verification.verify');

    Route::post('email/verification-notification', [EmailVerificationNotificationController::class, 'store'])
        ->middleware('throttle:6,1')
        ->name('verification.send');
		...
		});

The verification url looks something like:

https://{{APP_URL}}/verify-email/5/e34c48146999087b319d4d58f9fdac4d17fc9afe?expires=1712240915&signature=46e74947e7d8cd23418c2563575f8cde8a43df0642bde536e2a4b1fe9bc312fd

This works perfectly fine in localhost, using docker and sail, but in production throws 403 error. Am I missing something ? Please Help.

0 likes
7 replies
LaryAI's avatar
Level 58

It seems like you're encountering a 403 Unauthorized error when trying to verify emails in your production environment. This could be due to a number of reasons, but here are a few things you should check:

  1. Environment Configuration: Ensure that your APP_URL environment variable is set correctly in your production environment. This URL is used to generate the verification link, and if it's incorrect, the signature validation will fail, resulting in a 403 error.

  2. HTTPS Configuration: If your production environment uses HTTPS, make sure that your application is configured to generate secure (HTTPS) URLs. You can enforce this by setting the APP_URL with https:// and also by setting the SECURE_COOKIES environment variable to true if you are using secure cookies.

  3. Caching Configuration: If you have caching enabled, try clearing your route cache. Sometimes, the cached routes can cause issues with signed URLs. You can clear the route cache by running the following command:

php artisan route:cache
  1. Middleware Issues: The signed middleware is responsible for validating the signature of the verification URL. If the signature doesn't match, it will result in a 403 error. This could happen if the URL is being modified in any way after it's generated.

  2. Queue Worker: If you're using queues to send emails, make sure your queue workers are restarted after any deployment or environment changes to ensure they have the latest configuration.

  3. Frontend Caching: If you're using a service like Cloudflare or have any aggressive caching on your web server, make sure that the verification URLs are not being cached.

  4. Server Configuration: Check your server configuration (Nginx, Apache, etc.) to ensure that it's not stripping out or altering query parameters, which are essential for the signed URL to work correctly.

  5. Verify Email Class: Double-check your WelcomeUserNotification class to ensure that it extends the correct VerifyEmail class and that there are no typos or issues with the namespace.

If none of these solutions work, you may need to do further debugging. You can log the generated URL in both your local and production environments to compare them and ensure they match. Additionally, you can temporarily modify the VerifyEmailController to log the request and any exceptions that might be thrown to get more insight into what's happening.

Remember to revert any temporary debugging changes before going back to production to avoid any security issues.

DhPandya's avatar

@bi3_joe Have you configured your email settings on the production? After you configure it do not forgot to run php artisan optimize:clear.

bi3_dev's avatar

@DhPandya Yes I have the correct environment variables for production as well. Users receive the verification email. The problem is I still keep getting 403 error when I click on the link that should actually verify the email either via action button or via the URL, which is also provided in the email.

Surprisingly, everything works in local environment and the account gets verified.

Snapey's avatar

@bi3_joe Are sessions working OK? Do you have users that can login?

Are you prompted to login when verifying the token?

Make sure you are not logged in as yourself when trying to click the link.

bi3_dev's avatar

@Snapey Sorry for the late reply, I was working on other parts of the application. I have upgraded to Laravel 11 and everything works successfully except this issue still exists.

Yes, I have made sure I am not already logged in besides, I am receiving the emails on another PC as well. Things go smoothly until actual button that should redirect to home page after being verified does not work, email does not get verified and throws 403 error. User can login and get prompted to verify email, then they have option to resend the email as well, which still sends 403.

The only thing I have modified is the email, tried with default email as well. I have not changed any existing logic. And the problem seems to exist in my another project as well. Both projects are based on TALL and Breeze.

In localhost, everything works as intended and I can see the email_verified_at column getting the timestamp.

I have been able to fix other issues. This one seems strange because there is nothing log about it. I am assuming it is not an error and I don't know if I am missing something. I can't see anything relevant in the deployment documentation either.

Please or to participate in this conversation.