You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()
    ]);
}

关键修复点

  1. find($email)错误:find()默认按主键ID查找,需用where('email', $request->email)->first()根据邮箱获取管理员对象。
  2. 密码校验错误:Laravel默认哈希存储密码,创建管理员时需用Hash::make($password)加密,校验时必须用Hash::check($明文密码, $哈希密码)。
  3. get()返回集合问题:get('password')返回Eloquent集合,不是单个字段值,直接复用$admin->password更高效。
  4. redirect未return:redirect()->to()仅创建响应对象,必须return才能让Laravel执行跳转。
  5. update参数错误:update()需传入关联数组['字段名' => '值'],而非索引数组。
  6. 减少重复查询:找到管理员对象后直接复用,避免多次查询数据库。

内容的提问来源于stack exchange,提问作者Hacker Rhino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 18:45:31