2
votes

I set up a Laravel 8 installation with Jetstream and implemented a custom user registration, where an event is fired after a successful creation of the database record event(new Registered($user));.

The initial registration process should not require a password yet, because only a selected set of users should be able to login to a dashboard in the future.

After the registration the user gets an email with a verification link, however he still needs to login in order to get verified.

I tried to remove the auth middleware in routes/web.php, however i get an error message after attempting to verify a users email address.

Route::get('/email/verify/{id}/{hash}', function (EmailVerificationRequest $request) {
  $request->fulfill();
  return view('home');
})->middleware(['auth','signed'])->name('verification.verify');

Is it possible to verify a users email address without login information?

2

2 Answers

2
votes

It is possible.

You can modify files directly in Jetstream packages however I will present method adding new files and keeping original packages untouched.

Add new Controller App\Http\Controllers\VerifyEmailController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Auth\Events\Verified;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use App\Models\User;

class VerifyEmailController extends Controller
{

    public function __invoke(Request $request): RedirectResponse
    {
        $user = User::find($request->route('id')); //takes user ID from verification link. Even if somebody would hijack the URL, signature will be fail the request
        if ($user->hasVerifiedEmail()) {
            return redirect()->intended(config('fortify.home') . '?verified=1');
        }

        if ($user->markEmailAsVerified()) {
            event(new Verified($user));
        }
        
        $message = __('Your email has been verified.');

        return redirect('login')->with('status', $message); //if user is already logged in it will redirect to the dashboard page
    }
}

In web.php add a new route without auth middleware:

use App\Http\Controllers\VerifyEmailController;

...


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

On the end clear routes cache:

php artisan route:cache
0
votes

Open config/fortify.php file and uncomment the Features::emailVerification(), line.

'features' => [
    Features::registration(),
    Features::resetPasswords(),
    // Features::emailVerification(),
    Features::updateProfileInformation(),
    Features::updatePasswords(),
    Features::twoFactorAuthentication([
        'confirmPassword' => true,
    ]),
],

Next go to the User modal and implement the MustVerifyEmail interface.

class User extends Authenticatable implements MustVerifyEmail{
   use Notifiable;

}

Note: you should have knowledge about Mail in Laravel