تعداد بازدید: 2189

Validation Rules

وقتی بحث از ورود اطلاعات توسط کاربر پیش میاد بحث امنیت هم بعد از اون مطرح میشه. در لاراول روالی برای validate کردن اطلاعات کاربر داریم که با استفاده از اون هم میشه داده های مجاز رو تعیین کرد هم نکات امنیتی رعایت میشه.

نکته : در پایگاه داده لاراول از متد های PDO استفاده میشه که از SQL Injection جلوگیری می کنه.

لاراول برای پیاده سازی سیستم validation از شئ request استفاده میکنه ، که در اون قوانین (rules) تعریف می کنه که به ازای هر فیلد مقادیر مجاز و غیر مجاز تعیین میشه و در ازای مقدار مجاز کد اجرا میشه و در ازای مقدار غیر مجاز کد ادامه پیدا نمی کنه و شئ $errors ایجاد میشه .

اعتبار سنجی از Route تا Controller

فرض کنید ما در Route دو endpoint تعریف کردیم که یکی فرم ثبت محصول را نمایش می دهد و دیگری با متد post اطلاعات کاربر را برای ذخیره به controller می فرستد :

Route::get('admin/new-product/','ProductController@create')->name('product.create');
Route::post('admin/','ProductController@store')->name('product.save');

ما در قسمت controller متدی با نام newProduct داریم که فرم ساخت محصول را به کاربر نمایش می دهد و متد دیگری با نام saveProduct داریم که با استفاده از اطلاعاتی که کاربر بوسیله فیلد های فرم ارسال کرده یک محصول می سازه.

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\products;

class ProductController extends Controller
{
    public function create()
    {
        return view('product.create');
    }

    public function store(Request $request)
    {
        $product = $request->all();
        $validatedData = $request->validate([
           'name' => 'required|unique:products',
           'price' => 'required|numeric',
        ]);
        $product = $request->except('_token');
        $result = products::create($product);
        return redirect('/products');
    }
}
  • متد store شئ request را فراخوانی کرده است که بوسیله آن بتواند از متد validate استفاده کرده و validation rule را تعریف کند.
  • نوع شئ request هم مهم است که از چه کلاسی instanse شده باشد. شئ request که در مثال بالا استفاده شده از Illuminate\Http\Request می باشد .
  • ما به ازای هر فیلد می توانیم validation rule تعریف کنیم که قوانین آن را می توانید از اینجا مشاهده فرمایید. علاوه بر آن می توان از لیست ترجمه های فایل lang.validation (مثلا برای زبان انگلیسی در مسیر laravel\resources\lang\en\validation.php)قوانین اعتبار سنجی را ببینیم.

همچنین می توان از Custome Request استفاده کرد و در متد rule آن validation rule را پیاده سازی کرد.

public function rules()
{
	return [
		'name' => 'required|unique:products',
		'price' => 'required|numeric',
		'weight' => 'numeric|nullable'
	];
}

فرم ساخت محصول به شکل زیر خواهد بود . در متد newProduct فایل new-product.blade.php فراخوانی شده است که حاوی اطلاعات زیر است :

    @include('errors.crate')
    <form action="{{route('save.product')}}" method="POST">
        {{ csrf_field() }}
        <div class="form-group">
            <input type="text" class="form-control" id="product-name" name="name" value="{{old('name')}}" aria-describedby="productName"
                placeholder="product name">
            <small id="nameHelp" class="form-text text-muted">{{__('general.name_tip')}}</small>
        </div>
        <div class="form-group">
            <input type="text" class="form-control" id="product-price" name="price" value="{{old('price')}}" placeholder="price">
            <small id="priceHelp" class="form-text text-muted">{{__('general.price_tip')}}</small>
        </div>
        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
  • همان طور که می دانید هر Route دارای یک نام است که Path آن با استفاده از تابع route قابل دسترسی است که ما در کد بالا مسیر مسیر route دوم را به عنوان action فرم تعیین کرده ایم همچنین متد post را برای آن انتخاب کرده ایم که هر دوی این موارد بر اساس route دوم است.
  • تابع کمکی old برای این است که کاربر اگر به هر دلیل (محتمل ترین دلیل عدم تایید از سوی validation rule های request است) محصولش ساخته نشد داده هایی که در فرم وارد کرده برایش باقی بماند.
  • در ابتدای کد قالب errors.create فراخوانی شده است که محتوای آن خطاهایی است که در صورت غیر مجاز شناخته شدن مقادیر فیلد های کاربر نمایش داده می شود.
  • تابع کمکی csrf_field برای جلوگیری csrf protection استفاده می شود و وجود آن اجباری است و در غیر اینصورت request نامعتبر و خطای 419 یعنی همان session expired هدایت می شوید.

نتیجه فرم ساخت محصول

نتیجه فرم ساخت محصول به همراه اعتبارسنجی آن دو حالت زیر است :

تایید مقادیر فیلد ها و ساخت محصول :‌ در این صورت فیلد ها از فیلتر validation rules رد شده و معتبر شناخته شده و ادامه کد ها اجرا شده و محصول ساخته می شود.

عدم تایید مقادیر فیلد ها و خطا : فیلد ها توسط validation rules نامعتبر شناخته شده و ادامه کدها (ساخت محصول و بازگشت به داشبورد) اجرا نمی شود و صفحه جاری (new-product.blade.php) به همراه شئ $errors دوباره درخواست داده می شود و ما با استفاده از متد all خطاهای بوجود آمده بر اساس validation rules را چاپ می کنیم.

نحوه چاپ خطاها که در فایل create.blade.php با مسیر errors.create فراخوانی شده بود به شکل زیر می باشد:

@if ($errors->any())
<div class="alert alert-danger">
    <ul>
        @foreach ($errors->all() as $error)
        <li>{{ $error }}</li>
        @endforeach
    </ul>
</div>
@endif

CSRF Protection

ما Middleware مشترکی در route هامون داریم تحت عنوان web که در اون درخواستی معتبره که token مربوط به لاراول رو داشته باشه.

پس هر request معتبر در لاراول باید csrf token رو داشته باشه در غیر این صورت به صفحه 404 هدایت میشه. حال این که request ما از نوع post و از طریق فرم باشه که باید خودمون این فیلد رو بهش اضافه کنیم (بوسیله Helper Function) و یا از طریق route باشه که خود لاراول این کار رو برای ما می کنه.

ما در فرم ها با استفاده از تابع csrf_field می تونیم این فیلد رو به صورت hidden بسازیم و درخواستمون رو معتبر کنیم.

Creation Form Request

مثلا ما با استفاده از دستور زیر یک Request می سازیم.

php artisan make:request StoreBlogPost

در کلاس Request شخصی که توسط ما ساخته شده باشه متدی وجود داره که به وسیله اون میشه validation rule رو تعریف کرد و در نهایت در controller ما به وسیله شئ ساخته شده می تونیم validate رو انجام بدیم.

public function rules()
{
    return [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ];
}

خوب متد بالا برای تعریف validation rule بود و در نهایت با استفاده از شئ ساخته شده از Custome Request می تونیم فیلتر رو انجام بدیم.

public function store(StoreBlogPost $request)
{
    // The incoming request is valid...

    // Retrieve the validated input data...
    
}

خوب همون طور که مشاهده می کنید ما از شئ $request مورد نظر بر گرفته از کلاس StoreBlogPost استفاده می کنیم که خود validation رو انجام میده. پس ما دیگر نیازی به اجرای متد validate نداریم.

Validation Rules

در controller ما تعدادی قانون با استفاده از متد validate ایجاد کردیم . در این قسمت میخوایم در رابطه با نحوه ایجاد اون ها و لیست validation rule ها صحبت کنیم.

validation rule چه در Custom Request باشه (متد rule ایجاد شده موجود در Request ایجاد شده) و چه با استفاده از متد validate از شئ request موجود در Illuminate\Http\Request آرایه ای خواهد بود که هر المنت آن متشکل از نام فیلد مورد نظر برای فیلتر گذاری . به شکلی که index هر المنت از آرایه نام فیلد و مقدار آن برابر validation rule هایی که با | از هم جدا شده اند.

برخی از rule های موجود در Laravel Validation Rules :

accepted : این rule به معنای این است که این فیلد حتما باید مقدار true و یا 1 بگیرد. این فیلد برای تعیین چک باکس قبول قوانین و مقررات مناسب است.

required : به معنای الزامی بودن فیلد است.

unique:table,column : به معنای یکتا بودن مقدار فیلد در پایگاه داده بر اساس column می باشد. در صورتی که column تعیین نشده باشد از نام فیلد به عنوان نام ستون استفاده می شود.

'name' => 'required|unique:products'

در مثال بالا نام باید در جدول products و در ستون name یکتا باشد. یعنی نام وارد شده در جدول از قبل وجود نداشته باشد. (this name is already taken).

numeric : فیلد فقط مقادیر عددی را می پذیرد.

Error Messages

متن خطاهای چاپ شده در صورت غیر مجاز بودن مقدار فیلد در صورتی که ما از شئ instanse شده از کلاس Illuminate\Http\Request استفاده کنیم در فایل resourses/lang/en/validation.php موجود است.  حال این که در config/app.php شما مقدار locale را برابر چه مقداری قرار داده باشید زبان مورد نظر لود می شود.

ساختار های زیر قابل ترجمه هستند:

Custom Validation Attributes : نام فیلد های موجود در فرم مثل name , username , price و سایر فیلد های تعیین شده از سمت شما که در متن ترجمه rule ها به شکل :attribute نمایش داده می شوند.
'attributes' => [
      'name' => 'نام'
],
Validation Language Lines : متون خطا . در متون مواردی دارد که نشانگر متن نیستند و معمولا با : شروع می شوند مثل :attribute  که به معنی field name است. در مثال زیر :attribute نام فیلد می باشد.
'accepted'             => ' فیلد :attribute باید پذیرفته شود'
Custom Validation Language Lines : در قسمت بالا ما به ازای هر rule یک متن خاص خواهیم داشت . اگر بخواهید که برای rule از فیلدی خاص متن منحصر به فرد خود را وارد کنید می توانید در قسمت دوم آن را مطابق با قالب زیر وارد کنید. هر خطا مربوط به هر فیلد می تواند به صورت شخصی متن خاص خود را داشته باشد.
    'custom' => [
        'attribute-name' => [
            'rule-name' => 'custom-message',
        ],
    ],
مثلا در فیلد weight و rule برابر numeric می توان متن زیر را وارد کرد.
    'custom' => [
        'weight' => [
            'numeric' => 'لطفا در وارد کردن متن دقت فرمایید',
        ],
    ]

Custom Request Error Messages

اگر ما برای validation یک Request ایجاد کرده باشیم می توانیم متون خطا را در متد messages با همان فرمتی که در بالا توضیحاتش رو دادیم به ازای Custom Validation Attributes و Validation Language Lines  و Custom Validation Language Lines وارد کنیم.

<?php 
   /**
     * Get custom messages for validator errors.
     *
     * @return array
     */
    public function messages()
    {
        return [
            'name.required' => 'please fill name field',
            'name.unique' => 'product name must be unique, :attribute is already taken',
            'price.required' => 'please fill price field',
            'price.numeric' => 'price field must be numeric',
            'weight.numeric' => 'weight field must be numeric'
        ];
    }

نکته : در صورتی که مقادیر را در این متد set نکنیم از مسیر پیش فرض فایل های ترجمه قسمت validation میخواند. مثلا در مسیر resourses/lang /en/validation.php به ازای زبان انگلیسی در تنظیمات config.

اشتراک گذاری :

مدیر وب سایت گنوتک . برنامه نویسی رو با زبان C در هفده سالگی شروع کردم . در حال حاضر به برنامه نویسی php برپایه معماری MVC , HMVC و همچنین سیستم مدیریت محتوای WordPress و فریم ورک محبوب لاراول علاقه مند هستم و دوست دارم اطلاعاتم رو با شما به اشتراک بگذارم.

۰ دیدگاه برای Validation Rules

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *