آموزش laravel mass assignment

دسته بندی: لاراول
سطح مقاله: متوسط
زمان مطالعه: 7 دقیقه
۰۴ مرداد ۱۳۹۹

یکی از مهم‌ترین بخش‌های آموزش لاراول که در زمان کار با دیتابیس یا Model‌ها با آن سر و کار داریم، Mass Assignment است، که رعایت نکردن آن باعث به خطر افتادن جدی امنیت سایت می‌شود. اما این عبارت به چه معنا است؟ چرا رعایت نکردن laravel mass assignment می‌تواند، امنیت وب سایت شما را در معرض خطر قرار دهد، و چگونه می‌توان از این خطرات جلوگیری کرد؟ جواب این سوال‌ها را در ادامه خواهید یافت.

Mass Assignment

همان‌طور که در ابتدا گفتیم Mass Assignment یکی از مهم‌ترین بخش‌های آموزش لاراول است، که رعایت نکردن آن باعث به خطر افتادن امنیت سایت می‌شود.

mass assignment laravel

به‌طور مثال فرض کنید، یک 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 مواجه می‌شود، که کاملا امن است.

اگر به یادگیری بیشتر لاراول علاقه دارید می‌توانید در دوره آموزشی لاراول کاربردی (بسته پروژه محور) شرکت کنید، این دوره شامل ۱۲ پروژه کاربردی و پر استفاده در دنیای واقعی است، که تمامی پروژه‌ها به صورت کامل برنامه‌ نویسی خواهند شد، تا دانشجو بتواند با روند ایجاد و تکمیل پروژه به صورت کامل آشنا شود.

 

 

چه امتیازی به این مقاله می دید؟
نویسنده علی مجیدی
Backend Developer | PHP & Laravel Developer

نظرات کاربران

سالار

سلام ، ممنون از آموزش خوبتون
میشه توضیح بدید بعد از اینکه داخل مدل فیلد 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 استفاده کرد؟
ممنونم

ارسال دیدگاه
خوشحال میشیم دیدگاه و یا تجربیات خودتون رو با ما در میون بذارید :