I’m building an API using Laravel 10 with Sanctum for authentication, and I’m encountering an issue with email verification. After the user clicks the verification link, the email_verified_at field remains null.
This is my register component
import React from "react";
import { useNavigate } from "react-router-dom";
function Register() {
const [name, setName] = React.useState("");
const [email, setEmail] = React.useState("");
const [password, setPassword] = React.useState("");
const navigate = useNavigate();
React.useEffect(() => {
if (localStorage.getItem("token")) {
navigate("/account");
window.location.reload();
}
}, []);
async function register() {
const item = { name, email, password };
let result = await fetch("http://localhost:8000/api/register", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(item),
});
const data = await result.json();
if (result.ok) {
alert("Please verify your email before logging in.");
navigate("/login");
} else {
alert(data.message || "Error registering.");
}
}
return (
);
}
export default Register;
This is my auth controller
json(['message' => 'User not found.'], 404);
}
if (!hash_equals(sha1($user->getEmailForVerification()), $hash)) {
return response()->json(['message' => 'Invalid verification link.'], 400);
}
if ($user->email_verified_at) {
return response()->json(['message' => 'Email already verified.']);
}
$user->email_verified_at = Carbon::now();
$user->save();
return response()->json(['message' => 'Email verified successfully.']);
}
public function resendEmailVerification(Request $request)
{
if ($request->user()->hasVerifiedEmail()) {
return response()->json(['message' => 'Email already verified.']);
}
$request->user()->sendEmailVerificationNotification();
return response()->json(['message' => 'Verification email sent.']);
}
public function register(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|unique:users',
'password' => 'required|string|min:6'
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password)
]);
$user->sendEmailVerificationNotification();
$token = $user->createToken('auth_token')->plainTextToken;
return response()->json(['token' => $token, 'user' => $user], 201);
}
public function login(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required'
]);
$user = User::where('email', $request->email)->first();
if (!$user || !Hash::check($request->password, $user->password)) {
return ["error" => "Invalid credentials"];
}
$token = $user->createToken('auth_token')->plainTextToken;
return response()->json(['token' => $token, 'user' => $user]);
}
public function logout(Request $request)
{
$request->user()->tokens()->delete();
return response()->json(['message' => 'Logged out']);
}
public function user(Request $request)
{
return response()->json($request->user());
}
}
These are my api routes
get('/user', function (Request $request) {
return $request->user();
});
Route::post("/login",[AuthController::class,"login"]);
Route::post("/register",[AuthController::class,"register"]);
Route::middleware('auth:sanctum')->post('/addOrder', [OrderController::class, 'addOrder']);
Route::middleware('auth:sanctum')->post('/pay', [StripeController::class, 'pay']);
Route::middleware('auth:sanctum')->get('/displayOrders', [DisplayController::class, 'displayOrders']);
Route::get('/email/verify/{id}/{hash}', [AuthController::class, 'verifyEmail'])
->middleware(['signed'])
->name('verification.verify');
And these are my web routes
name('login');
Route::get('/email/verify/{id}/{hash}', [AuthController::class, 'verifyEmail'])
->middleware(['auth:sanctum', 'signed'])
->name('verification.verify');
I already made sure that the user model has the email verification thing enabled. Simply , after I receive the confirmation email on mailtrap and click the button I am getting redirected to the login page and then when checking the data base the “email_verified_at” entry is still empty… pls help