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 پرداختیم، اگر می خواهید همه ی مسائل امنیتی را رعایت کنید، باید بگوییم که در هر صورت استفاده از روش بیشتر به نفع شما است. چرا که هنگام استفاده از guarded ممکن است، فیلدهای اضافه ی دیگری به غیر از فیلدهای جدول مورد نظرمان به همراه Request کاربران ارسال شوند. در این صورت اگر از guarded استفاده کرده باشیم، کاربر به خطای دیتابیس برخورد خواهد کرد، چرا که لاراول تلاش می کند، اطلاعات را درون ستون هایی بریزد، که وجود خارجی ندارند، اما در صورت استفاده از برنامه با Exception مواجه می شود، که کاملا امن است.
اگر به یادگیری بیشتر لاراول علاقه دارید می توانید در دوره آموزشی لاراول کاربردی (بسته پروژه محور) شرکت کنید، این دوره شامل ۱۲ پروژه کاربردی و پر استفاده در دنیای واقعی است، که تمامی پروژه ها به صورت کامل برنامه نویسی خواهند شد، تا دانشجو بتواند با روند ایجاد و تکمیل پروژه به صورت کامل آشنا شود.
اشتراکگذاری:
۷ دیدگاه
نویسنده
Ali Majidi
سلام
ممنون از مقاله مفیدتون
فقط یه سوال
Mass Assignment زمانی میتونیم استفاده کنیم که اتریبوت name در فرم هامون == باشه با اسم ستون ها در دیتابیس درسته؟
یعنی مثلا اگر در فرم آدرس کاربر رو با اینپوتی که name ش name="address" باشه باید در دیتابیس هم ستونی به نام address داشته باشیم در Mass Assignment در غیر اینصورت با خطا مواجه میشیم درسته؟ خب حالا اگر در صورتی که فرممون تعداد فیلدای زیادی داشته باشه و بخوایم امنیت دیتابیسمون بیشتر بشه و مقدار name فیلد ها متفاوت با نام ستونشون در دیتابیس باشه آیا راهی هست که بشه از روش Mass Assignment استفاده کرد؟
ممنونم
سلام
ممنون از مقاله مفیدتون
فقط یه سوال
Mass Assignment زمانی میتونیم استفاده کنیم که اتریبوت name در فرم هامون == باشه با اسم ستون ها در دیتابیس درسته؟
یعنی مثلا اگر در فرم آدرس کاربر رو با اینپوتی که name ش name=”address” باشه باید در دیتابیس هم ستونی به نام address داشته باشیم در Mass Assignment در غیر اینصورت با خطا مواجه میشیم درسته؟ خب حالا اگر در صورتی که فرممون تعداد فیلدای زیادی داشته باشه و بخوایم امنیت دیتابیسمون بیشتر بشه و مقدار name فیلد ها متفاوت با نام ستونشون در دیتابیس باشه آیا راهی هست که بشه از روش Mass Assignment استفاده کرد؟
ممنونم
سلام،در حال حاضر دارم php یاد میگیرم...اما همیشه از اینده این زبان برنامه نویسی میترسم (با وجود وردپرس،wix,webflow,...)و نتیجه خیلی از بحث های اینترنتی اینه که php به درد نمیخوره و در حال افوله(به دلیل وجود وبسایت سازهایی که ذکر کردم)...
خواستم بدونم امیدی هست برای یادگیری php ؟واینکه بازار کارش برا اینده چطوره ؟؟؟لطفا راهنمایی کنین ...خیلی گیج شدم ...
سلام ، ممنون از آموزش خوبتون
میشه توضیح بدید بعد از اینکه داخل مدل فیلد fillable یا guarded ایجاد کردیم $User->update($request->all());
به چه صورت باید بنویسیم؟
قسمت all() تغییر نمیکنه؟
ممنون
عالی بود ممنون
سلام
توضیحاتتون در مورد آسیب پذیری 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 و غیره بروزرسانی یا ایجاد شوند.
سلام
مرسی از مقاله خوبتون ولی یک سوالی ذهن منو مشغول کرده به عنوان مثال توی همین مقاله ما price رو بریم توی guarded$ که یعنی کاربر نمیتونه پرش کنه و کلا توی فرم مقدار دهی بشه وارد دیتابیس نمیشه الان اگر مدیر سایت بخواد قیمت رو تغییر بده چی guarded باز جلوی اون رو میگیره نمیگیره؟ اگر میگیره بایدی چه کرد؟