هر کاربر به سادگی می تواند URL یک وب سایت را تغییر دهد و با URL جدید درخواستی را به سرور ارسال کند. این دستکاری می تواند منجر به اقدامات ناخواسته شود. اگر چنین است، چگونه سرور باید اطمینان حاصل کند که این URL دستکاری نشده است؟ لاراول یک ویژگی به نام URL های امضا شده ارائه می دهد که دستکاری URL را محدود می کند.

شما میتوانید طراحی سایت خود را به تیم متخصص آی بولود بسپارید.

چرا استفاده از URL های امضا شده در لاراول مفید است؟


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

https://www.example.com/23/unsubscribe/culinary

 

در اینجا عدد "23" شناسه کاربری و موضوع مشترک "آشپزی" است. حال یک هکر یا به عبارتی کاربر می تواند با تغییر این پارامترها این آدرس را تغییر دهد و سپس بر روی لینک تغییر یافته کلیک کند تا درخواستی به سرور وب سایت شما ارسال شود. این سناریو می تواند منجر به رویدادهای ناخواسته مانند لغو اشتراک سایر کاربران از این موضوع شود. با استفاده از URL های امضا شده، می توان تا حدودی از درخواست های ایجاد شده با URL های اصلاح شده جلوگیری کرد.

آموزش ایجاد URL های امضا شده یا امن در لاراول

 

 

ایجاد URL های امضا شده در لاراول به سادگی ایجاد مسیرهای معمولی است، به جز چند تفاوت کلیدی. برای اینکه لاراول تأیید کند که این URL ها از زمان ایجاد تغییر نکرده اند، یک هش امضا به رشته پرس و جو URL متصل می شود. بیایید نگاهی بیندازیم که چگونه می توانیم یک URL امضا شده ایجاد کنیم و زمان انقضا را تعیین کنیم.

برای ایجاد یک مسیر امضا شده باید از نمای URL استفاده کنیم. اکنون می توانیم از signedRoute() یا temporarySignedRoute() استفاده کنیم. در مورد ما می خواهیم مسیر پس از مدت زمان مشخصی منقضی شود، بنابراین از گزینه دوم استفاده خواهیم کرد. متد temporarySignedRoute() دو آرگومان را می پذیرد. اولین نام یک مسیر است که اشاره ای به یک مسیر موجود است. آرگومان دومی که باید به متد() temporarySignedRoute ارسال کنیم، زمان انقضا خواهد بود. بیایید ببینیم که در کد چگونه به نظر می رسد.

برای مثال، می‌توانید یک لینک عمومی «لغو اشتراک» را اجرا کنید که با استفاده از URLهای امضا شده برای مشترکین شما ارسال می‌شود. از متد signedRoute() نمای URL برای تولید یک URL امضا شده به یک مسیر مشخص استفاده کنید:

use Illuminate\Support\Facades\URL;
 
return URL::signedRoute('unsubscribe', ['user' => 1]);

کد بالا رشته ای مانند این را برمی گرداند:

https://foo.test/users/1/unsubcribe?signature=f834ed8570e05de6c50ad10bd6abcf71e9867fcb14bdf2670b4bf572ce346f3b

این عالی است، اما چیزی که ما واقعاً می‌خواهیم این است که یک مهر زمانی انقضا داشته باشیم که در URL امضا شده کدگذاری شود، بنابراین وقتی لاراول مسیر را تأیید می‌کند، اطمینان حاصل کند که مهر زمانی انقضا سپری نشده است. باشه، عادلانه هست. برای رسیدن به آن، از متد () temporarySignedRoute استفاده خواهیم کرد.

use Illuminate\Support\Facades\URL;
return URL::temporarySignedRoute('unsubscribe'now()->addMinutes(30), ['user' => 1]

اکنون که URL امضا شده را آماده استفاده کرده ایم، باید درخواست های دریافتی را تأیید کنیم و برای انجام این کار دو گزینه داریم:

  

1 - با Middleware

لاراول یک میان افزار امضا شده ارائه می دهد که می توانیم از آن استفاده کنیم. ابتدا باید مطمئن شویم که میان افزار را در App\Http\Kernel قرار داده ایم

use Illuminate\Routing\Middleware\ValidateSignature;

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

اکنون می‌توانیم از آن در فایل مسیرهایمان مانند زیر استفاده کنیم:

 

Route::post('unsubscribe/{user}'UnsubscribeUser::class)->name('unsubscribe')->middleware('signed');

2 - استفاده از متد hasValidSignature() روی شی درخواست

1use Illuminate\Http\Request;
public function __invoke(Request $request)
{
    if (! $request->hasValidSignature()) {
           //.. do something
     }
}

یا می‌توانیم یک تماس برگشتی به مسیر خود ارسال کنیم تا بررسی کنیم درخواست دریافتی دارای امضای معتبر است:

use Illuminate\Http\Request;
Route::get('/unsubscribe/{user}'function (Request $request) {
    if (! $request->hasValidSignature()) {
        abort(401);
     }
})->name('unsubscribe');

3 - برسی مسیرهای امضا شده نامعتبر

هنگامی که شخصی از یک URL امضا شده بازدید می کند که منقضی شده است، یک صفحه خطای عمومی برای کد وضعیت HTTP 403 دریافت می کند. اکنون می‌توانیم آن را با تعریف یک بسته «renderable» سفارشی برای استثنای InvalidSignatureException در کنترل‌کننده استثنا، تغییر/سفارشی کنیم.

use Illuminate\Routing\Exceptions\InvalidSignatureException;
/**
 * Register the exception handling callbacks for the application.
 *
 * @return void
 */
public function register()
{
    $this->renderable(function (InvalidSignatureException $e) {
        return response()->view('error.link-expired', [], 403);
    });
}