درود دوستان! یکی از ویژگی‌های پرکاربرد لاراول Signed URL ها هست. این ویژگی برای اضافه کردن یک لایه امنیتی بیشتر به آدرس‌هایی که بصورت عمومی در دسترس هستن استفاده میشه.

فرض کنیم یک سرویس خبرنامه ایمیلی داریم و می‌خوایم برای کاربرانی که مایل به دریافت خبرنامه نیستن یک لینک لغو اشتراک بسازیم. برای مثال لینک لغو عضویت برای کاربر شماره ۹۰ می‌‌تونه به صورت زیر باشه:

http://example.com/unsubscribe/90

وقتی این کاربر روی این لینک کلیک می‌کنه دیگه هیچ ایمیلی دریافت نخواهد کرد. حالا تصور کنین یک شخص که به این لینک دسترسی داره، اون رو دستکاری می‌کنه و بجای ۹۰، از شماره ۸۰ استفاده می‌کنه. در صورت عضویت ایمیل کاربر شماره ۸۰ هم لغو میشه! و به این صورت می‌تونه برای بقیه کاربرا هم این عملیات رو انجام بده.

یه راه حل می‌تونه فعال کردن احراز هویت برای این لینک باشه. اما معمولاً لغو خبرنامه‌های ایمیلی بدون نیاز به احراز هویت انجام میشه و یا چون توسط سرویس‌های شخص ثالث و مجزا ارسال میشن، احراز هویت کاربردی نداره. اینجاست که Signed URL های لاراول به کار ما میان 👌

 

ساختن یک Signed URL

ابتدا فرض کنیم یک Named Route داریم مثل زیر:

Route::get('unsubscribe/{user_id}', '...')->name('unsubscribe');

 برای ساختن یک Signed URL برای این روت از متد signedRoute از کلاس URL استفاده می‌کنیم:

use Illuminate\Support\Facades\URL;

$url = URL::signedRoute('unsubscribe', ['user_id' => 429]);

به همین سادگی! آدرسی که تولید میشه به شکل زیر خواهد بود:

http://example.com/unsubscribe/429?signature=897fa0b2832a1ebf57726ae80576f9b900dba98dbc7cc670a85d0d83a0297dcf

همونطور که می‌بینیم یک پارامتر به اسم signature به آخر این آدرس اضافه شده که اختصاصی برای این آدرس هست. اگه یکی از خصوصیت‌های آدرس (مثلاً user_id) عوض بشه، این آدرس نامعتبر و ادامه فرآیند متوقف میشه.

 

اعتبارسنجی آدرس‌های Signed

ابتدا میدلور زیر رو به قسمت $routeMiddleware فایل app/Http/Kernel.php اضافه کنیم:

protected $routeMiddleware = [
    // ...
    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
];