اضافه کردن دادهها به Database همراه با Mass Assignment
یکی از مهمترین بخشهای آموزش لاراول که در زمان کار با دیتابیس یا Modelها با آن سر و کار داریم، Mass Assignment است، که رعایت نکردن آن باعث به خطر افتادن جدی امنیت سایت میشود. اما این عبارت به چه معنا است؟ چرا رعایت نکردن laravel mass assignment میتواند، امنیت وب سایت شما را در معرض خطر قرار دهد، و چگونه میتوان از این خطرات جلوگیری کرد؟ جواب این سوالها را در ادامه خواهید یافت.
Mass Assignment
همانطور که در ابتدا گفتیم Mass Assignment یکی از مهمترین بخشهای آموزش لاراول است، که رعایت نکردن آن باعث به خطر افتادن امنیت سایت میشود.
بهطور مثال فرض کنید، یک form با بخشهای نام و نام خانوادگی، شمارهی همراه، آدرس و رمز عبور داریم، که کاربر باید آن را تکمیل کنید. حال برای همین form در Database علاوه بر بخشهای بالا چند بخش دیگر مانند نقش کاربری که شامل Admin یا User، دسترسیها و بخشهای امنیتی مهم دیگری میشود داریم. در این صورت هر کاربری که دانش برنامهنویسی داشته باشد، میتواند هنگام تکمیل form با اعمال چند تغییر کوچک نقش کاربری خود را Admin وارد کند، و به راحتی به تمام اطلاعات سایت دسترسی پیدا کند.
برای جلوگیری از این Bugهای امنیتی، باید در همان ابتدا تعیین کنیم که چه field هایی میتواند مقدار بگیرد. برای این کار میتوانیم، از دو حالت guarded یا fillable استفاده کنیم.
fillable : در آرایهی fillable تمام Attribute هایی که میخواهیم بتواند از طرف کاربر مقدار بگیرد، را وارد میکنیم.
guarded : در آرایهی guarded تمام Attribute هایی که نمیخواهیم از طرف کاربر مقدار بگیرد، را وارد میکنیم.
هنگامی که یک Attribute را در fillable وارد کنیم، به طور خودکار تمام Attributeهای دیگر guarded میشوند. همچنین اگر یک Attribute را در guarded وارد کنیم، بهطور خودکار تمام Attributeهای دیگر fillable میشوند.
فرض کنید در مثالی، تنها میخواهیم ۲ Attribute غیرقابل پر کردن باشند، در این حالت بهتر است، بهجای وارد کردن Attribute هایی که قابل پر کردن میباشند، در fillable، آن Attribute هایی که غیرقابل پر کردن هستند، را در guarded وارد کنیم.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['name'];
}
در دستور بالا Attribute که میتواند مقدار بگیرد، را در fillable وارد کردیم، پس تمام Attributesها به جز name که fillable است، guarded میباشند.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* The attributes that aren't mass assignable.
*
* @var array
*/
protected $guarded = ['price'];
}
در دستور بالا Attribute که نمیتواند مقدار بگیرد، را در guarded وارد کردیم، پس تمام Attributesها به جز price که guarded است، fillable میباشند.
اضافه کردن دادهها به Database همراه با Mass Assignment
برای ایجاد مستقیم یک داده در Database همراه با قابلیت Mass Assignment، میتوانیم از firstOrCreate و firstOrNew استفاده کنیم.
firstOrCreate: این method ابتدا تلاش میکند تا با توجه به مقداری که به آن دادیم، یک record از Database و از طریق Model پیدا کند. در صورتی که این record در Database پیدا نشود، به صورت خودکار یک داده با همان اطلاعاتی که وارد کردیم، در Database ایجاد میشود.
firstOrNew: این method همانند firstOrCreate عمل میکند، با فرق اینکه در صورت پیدا نشدن record، به جای ایجاد آن record، یک record از نمونه یا instance آن Model را برمیگرداند.
// Retrieve flight by name, or create it if it doesn't exist...
$flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);
// Retrieve flight by name, or create it with the name, delayed, and arrival_time attributes...
$flight = App\Flight::firstOrCreate(
['name' => 'Flight 10'],
['delayed' => 1, 'arrival_time' => '11:30']
);
// Retrieve by name, or instantiate...
$flight = App\Flight::firstOrNew(['name' => 'Flight 10']);
// Retrieve by name, or instantiate with the name, delayed, and arrival_time attributes...
$flight = App\Flight::firstOrNew(
['name' => 'Flight 10'],
['delayed' => 1, 'arrival_time' => '11:30']
);
updateOrCreate : این method زمانی برای بروزرسانی یک داده استفاده میشود، که بخواهیم در صورت وجود نداشتن آن داده برای بروزرسانی، بهصورت خودکار همان داده در Database ایجاد شود.
// If there's a flight from Oakland to San Diego, set the price to $99.
// If no matching model exists, create one.
$flight = App\Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99, 'discounted' => 1]
);
جمعبندی:
در این مقاله به آموزش laravel mass assignment پرداختیم، اگر میخواهید همهی مسائل امنیتی را رعایت کنید، باید بگوییم که در هر صورت استفاده از روش fillable بیشتر به نفع شما است. چرا که هنگام استفاده از guarded ممکن است، فیلدهای اضافهی دیگری به غیر از فیلدهای جدول مورد نظرمان به همراه Request کاربران ارسال شوند. در این صورت اگر از guarded استفاده کرده باشیم، کاربر به خطای دیتابیس برخورد خواهد کرد، چرا که لاراول تلاش میکند، اطلاعات را درون ستون هایی بریزد، که وجود خارجی ندارند، اما در صورت استفاده از fillable برنامه با Exception مواجه میشود، که کاملا امن است.
اگر به یادگیری بیشتر لاراول علاقه دارید میتوانید در دوره آموزشی لاراول کاربردی (بسته پروژه محور) شرکت کنید، این دوره شامل ۱۲ پروژه کاربردی و پر استفاده در دنیای واقعی است، که تمامی پروژهها به صورت کامل برنامه نویسی خواهند شد، تا دانشجو بتواند با روند ایجاد و تکمیل پروژه به صورت کامل آشنا شود.
۷ دیدگاه
علی کرم نیا۰۹ اسفند ۱۴۰۲، ۱۳:۲۱
سلام
مرسی از مقاله خوبتون ولی یک سوالی ذهن منو مشغول کرده به عنوان مثال توی همین مقاله ما price رو بریم توی guarded$ که یعنی کاربر نمیتونه پرش کنه و کلا توی فرم مقدار دهی بشه وارد دیتابیس نمیشه الان اگر مدیر سایت بخواد قیمت رو تغییر بده چی guarded باز جلوی اون رو میگیره نمیگیره؟ اگر میگیره بایدی چه کرد؟
بابک طیبی راد۱۲ آبان ۱۴۰۲، ۱۵:۰۷
سلام
توضیحاتتون در مورد آسیب پذیری mass assignment ناقص بود. چیزی که در مستندات لاراول اومده از این قراره:
A mass assignment vulnerability occurs when a user passes an unexpected HTTP request field and that field changes a column in your database that you did not expect. For example, a malicious user might send an is_admin parameter through an HTTP request, which is then passed to your model's create method, allowing the user to escalate themselves to an administrator.
و در ادامه هم توضیح میده که همواره در استفاده از متدهای save، create، fill و update به موضوع mass assignment توجه کنید.
توضیح بیشتر اینکه ممکنه شما قصد داشته باشید ستونی از جدول رو با محاسبه بر مبنای ستونهای دیگه پر کنید، در این صورت fillable به معنای << تمام فیلدهایی که میخواهیم بتواند از طرف کاربر مقدار بگیرد، را وارد میکنیم>> نیست. بلکه به معنای تمام فیلدهایی است که میتواند توسط متدهای fill، create و غیره بروزرسانی یا ایجاد شوند.
Faraidoun Ahmadi۲۱ آذر ۱۳۹۹، ۱۹:۰۹
عالی بود ممنون
سالار۲۲ اردیبهشت ۱۳۹۹، ۱۲:۵۰
سلام ، ممنون از آموزش خوبتون
میشه توضیح بدید بعد از اینکه داخل مدل فیلد fillable یا guarded ایجاد کردیم $User->update($request->all());
به چه صورت باید بنویسیم؟
قسمت all() تغییر نمیکنه؟
ممنون
Ali_Mousavi۲۱ تیر ۱۳۹۸، ۱۶:۵۶
سلام،در حال حاضر دارم php یاد میگیرم...اما همیشه از اینده این زبان برنامه نویسی میترسم (با وجود وردپرس،wix,webflow,...)و نتیجه خیلی از بحثهای اینترنتی اینه که php به درد نمیخوره و در حال افوله(به دلیل وجود وبسایت سازهایی که ذکر کردم)...
خواستم بدونم امیدی هست برای یادگیری php ؟واینکه بازار کارش برا اینده چطوره ؟؟؟لطفا راهنمایی کنین ...خیلی گیج شدم ...
امین۱۰ تیر ۱۳۹۸، ۱۸:۵۸
سلام
ممنون از مقاله مفیدتون
فقط یه سوال
Mass Assignment زمانی میتونیم استفاده کنیم که اتریبوت name در فرم هامون == باشه با اسم ستونها در دیتابیس درسته؟
یعنی مثلا اگر در فرم آدرس کاربر رو با اینپوتی که name ش name=”address” باشه باید در دیتابیس هم ستونی به نام address داشته باشیم در Mass Assignment در غیر اینصورت با خطا مواجه میشیم درسته؟ خب حالا اگر در صورتی که فرممون تعداد فیلدای زیادی داشته باشه و بخوایم امنیت دیتابیسمون بیشتر بشه و مقدار name فیلدها متفاوت با نام ستونشون در دیتابیس باشه آیا راهی هست که بشه از روش Mass Assignment استفاده کرد؟
ممنونم
امین۳۰ خرداد ۱۳۹۸، ۱۷:۱۹
سلام
ممنون از مقاله مفیدتون
فقط یه سوال
Mass Assignment زمانی میتونیم استفاده کنیم که اتریبوت name در فرم هامون == باشه با اسم ستونها در دیتابیس درسته؟
یعنی مثلا اگر در فرم آدرس کاربر رو با اینپوتی که name ش name="address" باشه باید در دیتابیس هم ستونی به نام address داشته باشیم در Mass Assignment در غیر اینصورت با خطا مواجه میشیم درسته؟ خب حالا اگر در صورتی که فرممون تعداد فیلدای زیادی داشته باشه و بخوایم امنیت دیتابیسمون بیشتر بشه و مقدار name فیلدها متفاوت با نام ستونشون در دیتابیس باشه آیا راهی هست که بشه از روش Mass Assignment استفاده کرد؟
ممنونم
شروع رایگان یادگیری برنامه نویسی
کلیک کنید 👇
دوره الفبای برنامه نویسی با هدف انتخاب زبان برنامه نویسی مناسب برای شما و پاسخگویی به سوالات متداول در شروع یادگیری موقتا رایگان شد: