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
相关产品推荐
相关产品推荐

