I'm currently making an API for a mobile app but I think I'm a bit confused with how email verification and authentication is meant to work. I'm attempting to implement the following flow:
However when the user clicks the email link a "route login not defined" error is rendered. Which makes sense, because the user is not authenticated at the time. But am I getting this wrong?
Should I authenticate the user prior to sending the email? And will that work, given that we're using Sanctum rather than "regular" authentication?
Currently this is what I'm doing:
// web.php
Route::get('/email/verify/{id}/{hash}', [EmailVerificationController::class, 'verify'])
->middleware('signed') //note that I don't use the auth or auth:sanctum middlewares
->name('verification.verify');
// EmailVerificationController.php
public function verify(Request $request)
{
$user = User::findOrFail($request->id);
if ($user->email_verified_at) {
return '';
}
if ($user->markEmailAsVerified()) {
event(new Verified($user));
}
return redirect()->away('app://open'); // The deep link
}
Is there any security risk here? Should I at any point authenticate the user before or after they click the link? I wanted to avoid rendering "web views" as much as possible.
I think that the best way is to implement two different paths based on the source of the user.
The user will just follow the link delivered by email, you can do that with or without authentication (maybe with transparent cookie authentication). If the validation is fulfilled redirect them back to the home page.
I would send a PIN (with some kind of expire mechanism) via email and ask them to put it inside the APP to verify the account. This can even be protected with auth middleware using the JWT token with the verification API call.
I don't see any security issue with this last one.