سلام آقای شیخ. باگ کوچکی در این پروژه وجود داره که با کمک چت جی پی تی رفعش کردم و با خودم گفتم قرار دادن راه حلش خالی از لطف نیست. اگه دوست داشتین این کامنت رو منتشر کنید که دوستان استفاده کنند یا هم فقط خودتون ببینید و در آینده لحاظش کنید. متن پیام من و چت جی پی تی : بعد از اینکه برای تغییر نقش کاربر، اطلاعاتشو ویرایش کردم، توی لاگین کردن مشکلی پیش اومد. وقتی میخوام لاگین کنم با خطای "رمز عبور اشتباه است" مواجه می شوم، در حالی که رمز درست رو وارد می کنم! کد کنترلر رو واسه ات میفرستم و اگه برای پیدا کردن دلیل مشکل به کد بخش دیگه ای هم نیاز داشتی بگو واسه ات بفرستم.
<?php
namespace App\Http\Controllers;
use App\Models\Role;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
class UserController extends Controller
{
public function index()
{
$users = User::latest()->with("roles")->paginate(20);
return view("users.index", compact("users"));
}
public function create()
{
$roles = Role::all();
return view("users.create", compact("roles"));
}
public function store(Request $request)
{
$request->validate([
"name" => "required|string",
"cellphone" => ["required", "regex:/^09[0-9]{9}$/", "unique:users,cellphone"],
"email" => "required|email|unique:users,email",
"password" => "required|min:6",
"role_ids" => "required",
"role_ids.*" => "exists:roles,id",
], [
"name.required" => "نام کاربر را وارد کنید",
"cellphone.required" => "شماره موبایل کاربر را وارد کنید",
"cellphone.regex" => "شماره موبایل وارد شده نامعتبر است",
"cellphone.unique" => "کاربری با این شماره موبایل وجود دارد",
"email.required" => "ایمیل را وارد کنید",
"email.email" => "ایمیل وارد شده نامعتبر است",
"email.unique" => "کاربری با این ایمیل وجود دارد",
"password.required" => "رمز عبور را وارد کنید",
"password.min" => "رمز عبور نباید کمتر از 6 کاراکتر باشد",
"role_ids.required" => "نقش کاربر را مشخص کنید"
]);
DB::beginTransaction();
$user = User::create([
"name" => $request->name,
"cellphone" => $request->cellphone,
"email" => $request->email,
"password" => Hash::make($request->password)
]);
$user->roles()->attach($request->role_ids);
DB::commit();
return redirect()->route("user.index")->with("success", "کاربر با موفقیت ایجاد شد");
}
public function edit(User $user)
{
$roles = Role::all();
return view("users.edit", compact("user", "roles"));
}
public function update(Request $request, User $user)
{
$request->validate([
"name" => "required|string",
"cellphone" => ["required", "regex:/^09[0-9]{9}$/", "unique:users,cellphone," . $user->id],
"email" => "required|email|unique:users,email," . $user->id,
"password" => "nullable|min:6",
"role_ids" => "required",
"role_ids.*" => "exists:roles,id",
], [
"name.required" => "نام کاربر را وارد کنید",
"cellphone.required" => "شماره موبایل کاربر را وارد کنید",
"cellphone.regex" => "شماره موبایل وارد شده نامعتبر است",
"cellphone.unique" => "کاربری با این شماره موبایل وجود دارد",
"email.required" => "ایمیل را وارد کنید",
"email.email" => "ایمیل وارد شده نامعتبر است",
"email.unique" => "کاربری با این ایمیل وجود دارد",
"password.min" => "رمز عبور نباید کمتر از 6 کاراکتر باشد",
"role_ids.required" => "نقش کاربر را مشخص کنید"
]);
DB::beginTransaction();
$user->update([
"name" => $request->name,
"cellphone" => $request->cellphone,
"email" => $request->email,
"password" => $request->has("password") ? Hash::make($request->password) : $user->password
]);
$user->roles()->sync($request->role_ids);
DB::commit();
return redirect()->route("user.index")->with("success", "اطلاعات کاربر با موفقیت ویرایش شد");
}
}
سلام همکار عزیز. این مشکل در متدهای update در لاراول بسیار رایج است و دلیل آن نحوه بررسی شرط has در کدهای شماست.
دلیل مشکل
در متد update شما از این خط استفاده کردهاید:
"password" => $request->has("password") ? Hash::make($request->password) : $user->password
متد request->has('password') همیشه true برمیگرداند، حتی اگر فیلد رمز عبور در فرم خالی باشد (چون کلید password در آرایه request وجود دارد). در نتیجه، لاراول سعی میکند مقدار “خالی” یا یک رشته تهی را با Hash::make هش کند و آن را در دیتابیس ذخیره کند. یعنی رمز عبور کاربر به جای اینکه تغییر نکند، به هشِ یک رشته خالی تغییر پیدا میکند! و به همین دلیل هنگام لاگین، رمز عبور اصلی شما با هشِ آن رشته خالی مطابقت ندارد.
راه حل
به جای has از متد filled استفاده کنید. متد filled تنها زمانی true برمیگرداند که مقدار فیلد خالی نباشد.
کد خود را به شکل زیر اصلاح کنید:
php
$user->update([
"name" => $request->name,
"cellphone" => $request->cellphone,
"email" => $request->email,
// تغییر در این خط: استفاده از filled به جای has
"password" => $request->filled("password") ? Hash::make($request->password) : $user->password
]);
چند نکته برای اطمینان بیشتر:
۱. تست مجدد: بعد از اعمال این تغییر، یک بار رمز عبور کاربر را از طریق دیتابیس (یا با یک ثبتنام جدید) اصلاح کنید و دوباره تست کنید.
۲. بررسی Blade: مطمئن شوید در فایل edit.blade.php فیلد رمز عبور شما حتماً دارای name="password" است (که قاعدتاً هست).
۳. توصیه امنیتی: در پروژههای بزرگتر، معمولاً برای ویرایش پروفایل، یک متد جداگانه یا یک FormRequest مجزا برای تغییر رمز عبور در نظر میگیرند تا با منطق ویرایش اطلاعات عمومی (نام و ایمیل) تداخل نداشته باشد، اما برای این مورد، استفاده از filled کاملاً مشکل شما را حل میکند.
taha
سلام استاد، خسته نباشید. خیلی ممنون بابت دورهی عالی و مفیدتون. 🙏
علی شیخ
7 روز پیش
سلام وقت بخیر.
ممنون از شما و حمایتتون🙏
خداروشکر دوره براتون مفید بوده