ورود و ثبت نام با رمز یکبار مصرف در لاراول

آقا این چه وضعیتی شده جدیدا هر کی سایت میخاد میگه که کاربر موقع ثبت نام شماره همراه وارد کنه و یه کد چند رقمی براش ارسال بشه و تایید بشه
یعنی این آخریا هر چی پروژه داشتم این قابلیت رو داشت :|
قشنگ شکرش رو در آوردن

حالا منم یه کدی برای این قضیه نوشته بودم هی از این پروژه میبردم به اون پروژه کپی و پیست و ... و همون زیر سوال بردن قائده DRY که خیلی زیاد دربارش به همه گفتم. تصمیم گرفتم به صورت یه پکیج درش بیارم تا هم لازم نباشه هی کپی پیست کنم و کلی کد بزنم هم اینکه دست به دامن متخصص های امنیت هم بشم که بیان یه نگاهی بندازن به چیزی که ساختم اگه باگی , راه نفوذی چیزی داره بهم خبر بدن و اگه راه حل بهتری نسبت به نگه داری آیپی دارن بهم بگن من پیاده سازی کنم هم روی سایت های قبلی که زدم آپدیت کنم و هم سایت های بعدیم خیالم راحت باشه مردم آزاری پیدا نمیشه بزنه شارژ پنل پیامکی رو خالی کنه.

تازه بقیه توسعه دهنده های لاراول هم اگه حال کردن میتونن ازش استفاده کنن, صفا کنن و دفعه بعد که خواستن چنین چیزی پیاده سازی کنن کارشون از همیشه راحت تر شده باشه :)

خب حالا اینجا به زبون فارسی صریح میخام بگم چجوری این پکیجی که ساختم رو استفاده کنین
استفاده ازش خیلی راحته و اینکه لازم نیست از پنل پیامکی خاصی استفاده کنین و با هر نوع پنل پیامکی روی این کره خاکی کار میکنه
حتی حتما لازم نیست پیامک باشه میتونه روش های دیگه مثل ایمیل هم باشه کی میدونه!

برای شروع با کمپوزر پکیج رو نصب کنین:

composer require sanjabteam/verify

بعد این دستور رو بزنین تا فایل کانفیگش به پوشه کانفیگ پروژه لاراول تون منتقل بشه

php artisan vendor:publish --provider=SanjabVerify\VerifyServiceProvider

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

<?php
namespace App\Helpers;
use SanjabVerify\Contracts\VerifyMethod;
class SmsVerifyMethod implements VerifyMethod
{
    public function send(string $receiver, string $code)
    {
        return send_sms($receiver, &quotYour code is : $code&quot);
    }
}

خب اینجا یه تابع خیلی ساده رو شما باید پیاده سازی کنین.
receiver : این پارامتر شماره کسی هست که باید براش پیامک فرستاده بشه
code: کد منحصر بفردی که باید برای کاربر پیامکش کنین
در نهایت باید اگه پیامک با موفقیت ارسال شد باید مقدار
true
return
کنین.

خب حالا بریم سراغ اصل مطلب:
شما باید در مجموع دوتا کار دیگه انجام بدین هر موقع که میخاین از قابلیت رمز عبور یه بار مصرف استفاده کنین.
1. ارسال
2. بررسی درستی کد

برای ارسال کد کافیه از این کد استفاده کنین:

use Verify;
use App\Helpers\SmsVerifyMethod;

$result = Verify::request($request->input('mobile'), SmsVerifyMethod::class);

که اینجا پارامتر اول شماره کسی هست که باید براش پیامک ارسال بشه. همونطور که گفتم این میتونه چیزای دیگه باشه مثل ایمیل بستگی داره اون کلاسی که بالاتر پیاده سازی کردین چه نوع گیرنده ای دریافت میکنه و کد رو چه شکلی ارسال میکنه
پارامتر دوم این دستور هم اسم اون کلاسی رو باید بدین که قبلا پیاده سازی کردین.
خب حالا خروجی این تابع یه آرایه هست به این شکل:
$result['success'] : اینکه آیا پیامک ارسال شد یا مشکلی وجود داره
$result['message'] : این پیامی هست که به کاربر نهایی نشون میدین
$result['seconds'] : این مورد فقط وقتی میاد که خطایی که رخ میده این باشه که کاربر اخیرا درخواست کد داده و چند ثانیه دیگه باید صبر کنه تا دوباره درخواست بده

قسمت دوم کار هم بررسی کدی هست که به کاربر فرستاده شده
برای اینکار یه Validation rule وجود داره که میتونین ازش استفاده کنین

$request->validate([
    'code' => 'required|sanjab_verify:mobile'
]);

اینجا منظور از mobile اسم فیلدی هست که مقدار گیرنده کد داخلشه و همزمان توی این درخواست اومده.
اگه نمیخاین از این روش استفاده کنین میتونین دستی هم کدش رو بنویسین به این شکل:

use Verify;

$result = Verify::verify($request->input('mobile'), $request->input('code'));
if ($result['success'] == false) {
    // Show error $result['message']
}

خب اینجا دوتا پارامتر میگیره پارامتر اول که شماره گیرنده ای هست که میخاین بررسی کنین کدی که براش ارسال شده رو داره درست وارد میکنه یا نه
پارامتر دوم هم کدی هست که کاربر وارد میکنه تا شما درست بودنش رو بررسی کنین.
خروجی این تابع هم مثل تابع بالایی هست که success نشونه موفق بودن یا نبودنه و message هم پیامی هست که میتونین به کاربر نشون بدین.

خب بذارین کارایی که همین الان این پکیج برای امنیت انجام میده رو بهتون بگم
اگه متخصص امنیتین و دیدین سوتی دادم ایمیل من رو روی گیت هابم میتونین پیدا کنین :) (ارادت ?✋)
با کانفیگ پیش فرض:
* هر کاربر با یه آی پی خاص یا شماره گیرنده خاص حداکثر هر 120 ثانیه یک بار اجازه داره درخواست دوباره کنه برای کد
* با یه سشن میتونه حداکثر سه بار در یک ساعت درخواست مجدد بده (که خب با پاک کردن کوکی قابل دور زدنه)
* با یه آپی خاص میتونه ده بار در یک ساعت درخواست مجدد کد بده (که خب اگه دو نفر همزمان از یه پراکسی بدون قابلیت فوروارد کردن آی پی استفاده کنن اگه یکیشون آزار رسانی کنه اون یکی این وسط میتونه مشکل ساز بشه براش)
* هر کاربر اجازه داره حداکثر 5 بار درخواست بده برای بررسی صحیح بودن کد که بعد از 5 بار اشتباه باید مجدد درخواست بده
* هر کاربر بعد اینکه کد صحیح رو وارد کرد کدش منقضی میشه و یه بار دیگه نمیتونه از همون استفاده کنه
* هر کاربر فقط تا ده دقیقه فرصت داره کدی که براش ارسال شده رو وارد کنه وگرنه زمانش از دست میره و باید از اول درخواست بده

خب حالا بحث کانفیگ و شخصی سازی کردن
به صورت پیش فرض پکیج یه کد عددی 6 رقمی به عنوان کد ارسال میکنه که شما میتونین با تغییر دادن محتویات آرایه code این تنظیمات رو تغییر بدین
length : طول کد
case_sensitive : اگه از حروف استفاده میکنین میتونین مشخص کنین حروف کوچک و بزرگ مهم باشه برای بررسی که خب پیشنهاد نمیکنم باعث میشه کاربرای عادی گیج بشن
numbers: اینکه کد شامل اعداد هم باشه یا نه
upper_case : اینکه کد شامل حروف بزرگ انگلیسی هم باشه یا نه
lower_case : اینکه کد شامل حروف کوچیک انگلیسی هم باشه یا نه
symbols: اینکه کد شامل علائم عجیب غریب هم باشه یا نه

resend_delay: بعد اینکه کاربر درخواست کد داد حداقل چند ثانیه اجازه نداره دوباره درخواست کد بده
expire_in : کدی که برای کاربر ارسال شد تو چند دقیقه منقضی بشه
max_attemps : کاربر تا چند بار اجازه داشته باشه کد اشتباه وارد کنه و بهش تذکر داده بشه
max_resends: تنظیمات محدودیت ارسال در یک ساعت
per_session : تو یک ساعت هر سشن چند بار اجازه داره درخواست کد بده
per_ip : تو یک ساعت هر آیپی چند بار اجازه داره درخواست کد بده

خب اینم از این.
امیدوارم یه کمکی شده باشه به توسعه دهنده های لاراول
اگه این پکیج رو دوست دارین حمایت کنین حتما داخل گیت هاب بهش ستاره بدین این کارتون کمک خیلی زیادی میکنه

https://github.com/sanjabteam/verify

دمتون گرم که این مطلب رو خوندین
تو جنگ با باگ ها موفق باشین ?

سایر نوشته هام:

https://virgool.io/@amiralizadeh9480/%D8%AA%D8%AC%D8%B1%D8%A8%D9%87-%D9%85%D9%87%D8%A7%D8%AC%D8%B1%D8%AA-%D8%A7%D8%B2-%D8%B2%D9%85%D9%BE-%D8%A8%D9%87-%D8%AF%D8%A7%DA%A9%D8%B1-%D8%A8%D9%87-%D9%87%D9%85%D8%B1%D8%A7%D9%87-%D9%86%DB%8C%D9%85-%D9%88%D8%AC%D8%A8-%D8%A2%D9%85%D9%88%D8%B2%D8%B4-hrwkfm0hrpth
https://virgool.io/laravel-community/%D8%A7%D8%AF%D9%88%DB%8C%D9%87-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-vumc46ozwcef
https://virgool.io/laravel-community/%D8%A7%D9%81%D8%B2%D9%88%D9%86%D9%87-%D9%85%D9%86-%D8%A8%D8%B1%D8%A7%DB%8C-vscode-%D9%88-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-mw9bcpvidbrd