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

Laravel密码重置报错:WHERE子句中不存在email列

Laravel密码重置使用手机号时出现「email字段不存在」错误

问题描述

尝试通过phone_number字段实现密码重置功能,已创建包含phone_number主键的password_reset_tokens表,但调用重置接口时出现以下错误:

Column not found: 1054 Unknown column 'email' in 'where clause' (Connection: mysql, SQL: select * from `password_reset_tokens` where `email` is null limit 1)

对应的迁移文件和控制器代码如下:

迁移文件

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('password_reset_tokens', function (Blueprint $table) {
            $table->string('phone_number')->primary();
            $table->string('token');
            $table->timestamp('created_at')->nullable();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('password_reset_tokens');
    }
};

控制器重置方法

public function resetPasswordConfirm(Request $request)
{   
    $request->validate([
        'token' => 'required',
        'phone_number' => 'required|exists:users,phone_number',
        'password' => 'required|min:5',
    ]);
    
    $response = Password::broker('users')->reset(
        [
            'phone_number' => $request->phone_number,
            'password' => $request->password,
            'password_confirmation' => $request->password_confirmation,
            'token' => $request->token,
        ],
        function ($user, $password) {
            $user->forceFill([
                'password' => Hash::make($password),
            ])->save();
        }
    );

    if ($response == Password::PASSWORD_RESET) {
        return response()->json(['message' => '密码已成功重置']);
    } else {
        return response()->json(['error' => '无法重置密码,请检查输入的信息。']);
    }
}

问题原因

Laravel默认的密码重置逻辑(包括Password Broker和TokenRepository)是基于email字段设计的,即使你传入phone_number,底层代码依然会默认使用email作为查询条件去查找令牌记录。

解决方案

1. 配置密码重置Broker使用手机号字段

修改config/auth.php文件,在passwords数组的users项中添加username配置,指定使用phone_number作为身份识别字段:

'passwords' => [
    'users' => [
        'provider' => 'users',
        'table' => 'password_reset_tokens',
        'expire' => 60,
        'username' => 'phone_number', // 新增此行
    ],
],

2. 修改用户模型指定认证字段

在App\Models\User模型中,添加$username属性或重写getAuthIdentifierName方法,告诉框架使用phone_number作为用户认证的唯一标识:

// 方式一:直接设置username属性
protected $username = 'phone_number';

// 方式二:重写方法(更灵活)
public function getAuthIdentifierName()
{
    return 'phone_number';
}

3. 确保生成重置令牌时使用手机号

如果是自己实现发送重置令牌的逻辑,要确保传递phone_number而非email给sendResetLink方法:

$response = Password::broker('users')->sendResetLink(
    ['phone_number' => $request->phone_number]
);

4. 自定义TokenRepository(可选,若上述配置不生效)

如果默认的TokenRepository依然强制使用email,可以创建自定义的令牌仓库类来替换:

创建自定义TokenRepository

<?php

namespace App\Auth\Passwords;

use Illuminate\Auth\Passwords\DatabaseTokenRepository;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

class PhoneNumberTokenRepository extends DatabaseTokenRepository
{
    protected function getPayload(CanResetPasswordContract $user, $token)
    {
        return [
            'phone_number' => $user->getAuthIdentifier(),
            'token' => $this->hasher->make($token),
            'created_at' => now(),
        ];
    }
}

在AuthServiceProvider中注册自定义Broker

use App\Auth\Passwords\PhoneNumberTokenRepository;
use Illuminate\Auth\Passwords\PasswordBroker;
use Illuminate\Support\Facades\Auth;

public function boot()
{
    $this->registerPolicies();

    Auth::broker()->extend('users', function ($app, $config) {
        $repository = new PhoneNumberTokenRepository(
            $app['db']->connection(),
            $app['hash'],
            $config['table']
        );

        return new PasswordBroker(
            $repository,
            $app['auth']->createUserProvider($config['provider'])
        );
    });
}

完成以上步骤后,框架就会使用phone_number字段来查询和生成密码重置令牌,不会再出现email字段不存在的错误。

内容的提问来源于stack exchange,提问作者Erkhan Djakhanov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 22:52:03