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

Laravel密码重置API问题:仅修改users表首个用户密码

Laravel密码重置异常:目标用户密码未变更,仅第一个用户密码被修改

我编写的Laravel密码重置代码无报错,但接收重置邮件的用户密码并未变更,反而users表中第一个用户的密码被修改,尝试多种方法仍未解决。以下是相关文件及代码:


相关文件代码

1. routes/api.php

Route::post('/forgetPassword',[UserController::class,'forgetPassword']);

2. routes/web.php

Route::get('/resetPassword',[UserController::class,'forgetPasswordLoad']);
Route::post('/resetPassword',[UserController::class,'resetPassword']);

3. app/Http/Controllers/Api/UserController.php

<?php

namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use App\Models\PasswordReset;
use Mail;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Hash;

class UserController extends Controller
{
    #reset password
    public function forgetPassword(Request $request)
    {
        try {
            $user = User::where('email',$request->email)->get();
            
            if (count($user)>0) {
                $token = Str::random(40);
                $domain = URL::to('/');
                $url = $domain.'/resetPassword?token='.$token;

                $data['url']=$url;
                $data['email']=$request->email;
                $data['title']="Password Reset";
                $data['body']="Please click on below link to reset password";

                Mail::send('API/forgetPasswordMail',['data'=>$data],function($message) use ($data){
                    $message->to($data['email'])->subject($data['title']);
                });

                $datetime = Carbon::now()->format('Y-m-d H:i:s');
                PasswordReset::updateOrCreate(
                ['email'=>$request->email],
                [
                    'email' => $request->email,
                    'token' => $token,
                    'created_at'=>$datetime
                ]
                );

                return response()->json(['success'=>true,'message'=>'Şifrenizi değiştirmek için lütfen mailinizi kontrol ediniz!']);
            }else {
                return response()->json(['success'=>false,'message'=>'Kullanıcı Bulunamadı']);
            }
        } catch (\Exception $e) {
            return response()->json(['success'=>false,'message'=>$e->getMessage()]);
        }
    }

    #reset password view load
    public function forgetPasswordLoad(Request $request) 
    {
        $resetData = PasswordReset::where('token',$request->token)->get();
        if (count($resetData)>0) {
            $user = User::where('email',$resetData[0]['email'])->get();
            return view('API/resetPassword',compact('user'));
        }else {
            return view('API/404');
        }
    }
   
    #reset password func
    public function resetPassword(Request $request)
    {
        try {
            $request->validate([
                'password' => 'required|string|min:6|confirmed'
            ]);
    
            $user = User::find($request->id);
            $user->password =$request->password;
            $user->save();
            return "<h1>Şifreniz Başarıyla Değiştirildi.Mobil Uygulamaya Dönebilirsiniz</h1>";
        }  catch (\Exception $e) {
            return response()->json(['success'=>false,'message'=>$e->getMessage()]);
        }
    }
}

4. resources/views/API/resetPassword.blade.php

<h1>Proxima Doktor</h1>
<form method="POST">
       @csrf
        <h3>Password Reset</h3>
        <p>Lütfen güçlü bir parola giriniz</p>
        <p>Password</p>
        <input type="hidden" name="id" value="{{$user[0]['id']}}">
        <input type="password" name="password">
        <i class="fa fa-eye-slash"></i>
        <p>Password Again</p>
        <input type="password" name="password_confirmation">
        <i class="fa fa-eye-slash"></i>
        <br><br>
        <input type="submit">
    </form>

5. app/Models/PasswordReset.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class PasswordReset extends Model
{
    use HasFactory;

    public $table = 'password_reset_tokens';
    public $timestamps = false;
    protected $primaryKey = 'email';

    protected $fillable = [
        'email',
        'token',
        'created_at'
    ];
}

问题原因及修复方案

1. 核心问题:错误使用get()导致取错用户ID

在forgetPasswordLoad方法中,User::where('email',$resetData[0]['email'])->get()返回的是用户集合,而非单个用户实例。当你在blade模板中用$user[0]['id']取值时,会直接取集合里的第一个用户ID,这就导致重置密码时修改了错误用户的密码。

修复:
将get()替换为first()获取单个用户实例:

// UserController.php 的 forgetPasswordLoad 方法中
$user = User::where('email',$resetData[0]['email'])->first();

同时修改blade模板的用户ID取值:

<input type="hidden" name="id" value="{{$user->id}}">

2. 次要问题:密码未加密存储

在resetPassword方法中,直接将明文密码赋值给$user->password,Laravel的User模型需要用Hash::make()加密密码,否则无法正常验证登录。

修复:
修改密码赋值代码:

// UserController.php 的 resetPassword 方法中
$user->password = Hash::make($request->password);

额外优化建议

  • 给users表的email字段添加唯一约束,避免出现同邮箱多用户的情况:
    ALTER TABLE users ADD UNIQUE (email);
    
  • 在forgetPassword方法中,同样用first()代替get(),逻辑更严谨:
    $user = User::where('email',$request->email)->first();
    if ($user) {
        // 后续逻辑
    }
    
  • 重置密码成功后删除对应重置记录,避免重复使用:
    取消resetPassword方法中注释的代码:
    PasswordReset::where('email',$user->email)->delete();
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:10:04