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

Laravel 8+Sanctum中Auth::attempt与Hash::check验证失败问题

问题排查与解决方案

你的登录接口返回Unauthorized的核心原因是Laravel认证系统默认的字段名与你的数据库大写字段不匹配,以下是具体修复步骤:

1. 修复认证字段匹配问题

Laravel的Auth::attempt()默认会使用小写的username(或email)作为用户名字段,但你的数据库是大写的USERNAME,同时需要确保密码验证时能正确读取到PASSWORD字段。

方案一:修改User模型,明确指定认证字段

在User模型中添加以下方法,告诉Laravel认证时使用的用户名和密码字段:

////
protected $table = 'users';
protected $guarded = ['ID'];

// 指定认证用的用户名字段
public function getAuthIdentifierName()
{
    return 'USERNAME';
}

// 指定认证用的密码字段(你已经写了这个,保留即可)
public function getAuthPassword()
{
    return $this->PASSWORD;
}
////

方案二:在LoginController的login方法中明确指定认证字段

如果不想修改模型,也可以直接在构造认证凭据时使用数据库的大写字段名:

public function login(Request $request)
{
    $data = $request->validate([
        'username' => 'required|string',
        'password' => 'required|string'
    ]);

    // 构造匹配数据库字段的凭据
    $credentials = [
        'USERNAME' => $data['username'],
        'password' => $data['password']
    ];

    if(!Auth::attempt($credentials)) {
        return response()->json([
            'message' => 'Unauthorized'
        ], 401);
    }

    // 通过Auth获取用户,避免字段名匹配问题
    $user = Auth::user();
    $token = $user->createToken('apiToken')->plainTextToken;

    $res = [
        'user' => $user,
        'token' => $token
    ];

    return response($res, 201);
}

2. 修复用户查询的字段名问题

原代码中User::where('username', $data['username'])->first()使用小写的username作为字段名,虽然MySQL默认不区分大小写,但为了严谨,建议改成与数据库一致的大写:

$user = User::where('USERNAME', $data['username'])->first();

验证修复效果

完成修改后,重新调用登录接口:

  • 若使用方案一,原Auth::attempt($credentials)可以保留,因为模型已经指定了正确的认证字段
  • 若使用方案二,凭据已经匹配数据库字段,认证逻辑会正常执行

额外检查项

  • 确认数据库中PASSWORD字段存储的是哈希值(注册接口已经用Hash::make()处理,这部分没问题)
  • 确保请求时传递的username和password参数正确,没有拼写错误

内容的提问来源于stack exchange,提问作者Hafid Maulana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 13:15:06