Laravel管理员登录表单数据验证、初始化及跳转问题求助
Laravel管理员登录校验问题
问题背景
我是Laravel新手,已搭建管理员登录表单、Admin模型、AdminLoginController及HTML页面,需求是获取表单提交的邮箱和密码,与MySQL数据库(PHPMyAdmin)中的管理员数据校验,验证通过则跳转至home视图。
目前遇到两个问题:
- 初始化
$info时服务器提示‘Attempt to read property "id" on array’ - 数据库数据校验逻辑存在问题,现有代码无法正确完成验证
相关代码
登录表单代码
<form action="{{ url('home/admin/',[$info->id]) }}" method="post" role="form" style=" width: 900px; display: flex; flex-direction: row; align-items: flex-end; " > @method('post') {{ csrf_field() }} <div class="input-label" style=" flex: 1; display: flex; flex-direction: column; " > <label for="email">Email:</label> <label for="password">Password:</label> </div> <div class="input-box" style=" flex: 6; display: flex; flex-direction: column; " > <input type="text" id="email" name="email" step="any" min="0" max="100" value="{{$info->email}}"/> <input type="text" id="password" name="password" step="any" min="0" max="100" value="{{$info->password}}"/> </div> <div> <input type="submit" value="Submit"/> </div> </form>
$info初始化代码
<?php $info = []; ?>
控制器代码
public static function loginCheckAdmin(Request $request): bool { $email = $request->email; $password = $request->password; if (Admin::query()->find($email) === null) { return false; } else { $fetchedPassword = Admin::query()->where('email',$email)->get('password'); if ($fetchedPassword === $password) { return true; } else { return false; } } } public static function redirectAdminToHome(Request $request) { if (self::loginCheckAdmin($request) === true) { $email = $request->email; $id = Admin::query()->where('email',$email)->get('id'); redirect()->to('home/admin'.$id); self::updateAdminLoginTime($request); } else { self::denyUserAccess($request); } } public static function denyUserAccess(Request $request) { echo("Invalid login process!"); } public static function updateAdminLoginTime(Request $request) { $email = $request->email; $lastLoginTime = Carbon::now()->toDateTimeString(); Admin::query()->where('email',$email)->update(['last_login_time',$lastLoginTime]); }
解决方案
问题1:修复$info初始化报错
你将$info初始化为数组[],但Blade模板中使用了对象属性访问语法$info->id、$info->email,数组无法通过->访问属性,因此报错。提供两种解决方式:
方案1:初始化空Admin对象
在视图的PHP代码中,初始化一个空的Admin模型实例:
<?php $info = new \App\Models\Admin(); // 替换为你的Admin模型实际命名空间 ?>
这样模板中$info->id会返回null,不会触发报错,输入框默认值为空,符合登录表单需求。
方案2:移除模板中$info相关依赖
登录页面无需传递已登录管理员信息,直接修改表单action和输入框:
<form action="{{ url('home/admin/login') }}" method="post" role="form" style="width: 900px; display: flex; flex-direction: row; align-items: flex-end;" > @method('post') {{ csrf_field() }} <!-- 其他结构不变 --> <input type="email" id="email" name="email" value=""/> <input type="password" id="password" name="password" value=""/> <!-- 其他结构不变 --> </form>
注意:密码输入框改用type="password",隐藏输入内容,提升安全性。
问题2:修复数据库校验逻辑
你的控制器代码存在多个逻辑错误,以下是重构后的完整代码及关键修复说明:
重构后的控制器代码
use Illuminate\Support\Facades\Hash; use Carbon\Carbon; public function loginCheckAdmin(Request $request) { // 先验证请求参数格式 $request->validate([ 'email' => 'required|email', 'password' => 'required', ]); // 根据邮箱查找管理员 $admin = Admin::where('email', $request->email)->first(); // 验证管理员存在且密码匹配(Laravel密码默认哈希存储,需用Hash::check校验) if (!$admin || !Hash::check($request->password, $admin->password)) { return false; } return $admin; // 返回管理员对象,避免重复查询 } public function redirectAdminToHome(Request $request) { $admin = $this->loginCheckAdmin($request); if ($admin) { // 更新登录时间 $this->updateAdminLoginTime($admin); // 跳转必须return才能生效,建议使用路由命名 return redirect()->route('home.admin', ['id' => $admin->id]); } else { $this->denyUserAccess(); // 返回登录页并携带错误提示 return back()->withErrors(['login' => '邮箱或密码错误']); } } public function denyUserAccess() { // 避免直接echo,返回标准HTTP响应 return response("Invalid login process!", 401); } public function updateAdminLoginTime($admin) { // 复用已查询的管理员对象,减少数据库请求 $admin->update([ 'last_login_time' => Carbon::now()->toDateTimeString() ]); }
关键修复点
find($email)错误:find()默认按主键ID查找,需用where('email', $request->email)->first()根据邮箱获取管理员对象。- 密码校验错误:Laravel默认哈希存储密码,创建管理员时需用
Hash::make($password)加密,校验时必须用Hash::check($明文密码, $哈希密码)。 get()返回集合问题:get('password')返回Eloquent集合,不是单个字段值,直接复用$admin->password更高效。- redirect未return:
redirect()->to()仅创建响应对象,必须return才能让Laravel执行跳转。 - update参数错误:
update()需传入关联数组['字段名' => '值'],而非索引数组。 - 减少重复查询:找到管理员对象后直接复用,避免多次查询数据库。
内容的提问来源于stack exchange,提问作者Hacker Rhino
相关产品推荐
相关产品推荐

