Laravel报Attempt to read property "email_verified" on null错误排查
报错信息
Attempt to read property "email_verified" on null

实现目标
用户注册后发送邮箱验证邮件,校验通过后才允许访问读者端后台。
报错触发原因
- 中间件挂载逻辑错误:
IsVerifiedEmail邮箱验证中间件被错误挂载到guest:reader游客可访问的路由组下,访问登录、注册、邮箱验证页面时用户处于未登录状态,Auth::guard('reader')->user()返回值为null,直接读取null的email_verified属性直接触发报错。 - 中间件缺少空值判断:即使中间件挂载位置正确,原有逻辑没有提前判断当前登录用户对象是否存在,遇到未登录用户访问受保护路由时同样会触发同类错误。
- 验证控制器存在语法错误:
verify方法中$reader = $$verifyReader->reader;多写了一个$变量符号,会导致变量解析异常,无法正确获取待验证的用户对象。 - 验证逻辑缺少兜底分支:原有
verify方法没有处理token无效(查不到对应验证记录)的场景,会出现返回响应缺失的问题。
修复方案
按以下步骤逐一调整代码即可解决问题:
- 调整路由中间件挂载位置
将IsVerifiedEmail中间件从游客路由组移除,挂载到需要登录后访问、且需要校验邮箱状态的路由组中:
Route::prefix('reader')->name('reader.')->group(function () { Route::middleware(['guest:reader', 'PreventBackHistory'])->group(function () { Route::view('/login', 'dashboard.reader.login')->name('login'); Route::view('/register', 'dashboard.reader.register')->name('register'); Route::post('/create', [ReaderController::class, 'create'])->name('create'); Route::post('/check', [ReaderController::class, 'check'])->name('check'); Route::get('/verify', [ReaderController::class, 'verify'])->name('verify'); }); // 已登录路由组新增邮箱验证中间件 Route::middleware(['auth:reader', 'PreventBackHistory', 'IsVerifiedEmail'])->group(function () { Route::view('/home', 'dashboard.reader.home')->name('home'); Route::post('logout', [ReaderController::class, 'logout'])->name('logout'); }); });
- 优化邮箱验证中间件逻辑,增加空值判断
修改IsVerifiedEmail中间件的handle方法,先校验用户登录状态再判断邮箱验证情况:
public function handle(Request $request, Closure $next) { $readerUser = Auth::guard('reader')->user(); // 未登录直接跳转登录页 if (!$readerUser) { return redirect()->route('reader.login')->with('fail', 'Please login first.'); } // 已登录但未验证邮箱则退出并跳转 if(!$readerUser->email_verified){ Auth::guard('reader')->logout(); return redirect()->route('reader.login')->with('fail','Need to verify email.')->withInput(); } return $next($request); }
- 修复验证控制器语法错误,补全兜底逻辑
修正多余的$符号,增加token无效场景的跳转处理:
public function verify(Request $request) { $token = $request->token; $verifyReader = VerifyReader::where('token', $token)->first(); // token无效直接跳转 if (is_null($verifyReader)) { return redirect()->route('reader.login')->with('fail', 'Invalid verification link.'); } // 修复多写$的语法错误 $reader = $verifyReader->reader; if (!$reader->email_verified) { $reader->email_verified = 1; $reader->email_verified_at = Carbon::now(); $reader->save(); return redirect()->route('reader.login')->with('info', 'Email Verified')->with('verifiedEmail', $reader->email); } else { return redirect()->route('reader.login')->with('info', 'Email Already Verified')->with('verifiedEmail', $reader->email); } }
- 补全模型关联(可选排查项)
确认VerifyReader模型中已经定义了和Reader的关联关系,否则无法通过$verifyReader->reader获取对应用户:
// VerifyReader模型内添加关联方法 public function reader() { return $this->belongsTo(Reader::class); }
内容的提问来源于stack exchange,提问作者TechRian
相关产品推荐
相关产品推荐

