پرش به مطلب اصلی

OTP و Verification

اگر پروژه شما از OTP برای login، activation یا reset password استفاده می‌کند، این متدها مهم‌ترین entry pointها هستند.

در flow پیش فرض panel، package این سناریوها را خودش هندل می‌کند. این صفحه برای وقتی است که بخواهید همان behavior را در controller یا endpoint سفارشی خودتان پیاده کنید.

API اصلی flow

void Authenticator::sendLoginOtp()
bool Authenticator::verifyLoginOtp(string $code)
array Authenticator::resendLoginOtp()
void Authenticator::sendOTPFor(UserActivationType $activationType)
object|null Authenticator::verifyOTPFor(UserActivationType $activationType, string $code)
array Authenticator::resendOTPFor(UserActivationType $activationType)
object|null Authenticator::getActivationByEncryptedId(string $encryptedActivationId)
bool Authenticator::changePasswordByActivationCode(string $encryptedActivationId, string $newPassword)

string userActivationModel()

Authenticator::sendLoginOtp(): void

برای کاربر جاری login OTP ارسال می‌کند، اما اگر کد معتبر قبلی هنوز معتبر باشد دوباره کد جدید تولید نمی‌کند.

پارامتر:

  • ندارد

Authenticator::verifyLoginOtp(string $code): bool

کد OTP ورود را برای کاربر جاری بررسی می‌کند و در صورت موفق بودن آن را مصرف‌شده علامت می‌زند.

پارامترنوعتوضیح
codestringکد واردشده توسط کاربر

Authenticator::resendLoginOtp(): array

اگر کد معتبر قبلی هنوز زنده باشد همان بازه انقضا را برمی‌گرداند، و اگر نه کد جدید می‌سازد.

پارامتر:

  • ندارد

خروجی:

  • expire_timestamp
  • is_regenerated

Authenticator::sendOTPFor(UserActivationType $activationType): void

برای سناریوهای غیر از login ساده استفاده می‌شود.

پارامترنوعتوضیح
activationTypeUserActivationTypeنوع جریان، مثل activation یا forget password

Authenticator::changePasswordByActivationCode(string $encryptedActivationId, string $newPassword): bool

رمز عبور را بر اساس activation record معتبر و مصرف‌شده تغییر می‌دهد.

پارامترنوعتوضیح
encryptedActivationIdstringشناسه رمزگذاری‌شده activation
newPasswordstringرمز عبور جدید

سناریوی واقعی: custom OTP login در panel یا API

use Dornica\AccessHub\Authentication\Facades\Authenticator;

Authenticator::user($user);
Authenticator::sendLoginOtp();

if (! Authenticator::verifyLoginOtp(request('code'))) {
return back()->withErrors([
'code' => 'کد وارد شده معتبر نیست.',
]);
}

در این سناریو معمولاً قبل از sendLoginOtp() این مراحل را هم انجام می‌دهید:

  1. با resolveAuthField() نوع credential را تشخیص می‌دهید.
  2. با useAuthField() فیلد فعال را ست می‌کنید.
  3. با findUserByCredential() کاربر را پیدا می‌کنید.
  4. با canLogin() مطمئن می‌شوید وضعیت کاربر اجازه ورود می‌دهد.

سناریوی واقعی: custom forgot password

use Dornica\AccessHub\Authentication\Enums\UserActivationType;
use Dornica\AccessHub\Authentication\Facades\Authenticator;

Authenticator::user($user);
Authenticator::sendOTPFor(UserActivationType::FORGET_PASSWORD);

$verifiedActivation = Authenticator::verifyOTPFor(
UserActivationType::FORGET_PASSWORD,
request('code')
);

if (! $verifiedActivation) {
return back()->withErrors([
'code' => 'کد بازیابی معتبر نیست.',
]);
}

بعد از تایید موفق کد، معمولاً مرحله بعدی این است:

Authenticator::changePasswordByActivationCode(
encryptValue($verifiedActivation->id),
request('password')
);

تنظیمات مهم کانفیگ

این رفتارها معمولاً از config/dornica-access-hub.php کنترل می‌شوند:

  • authentication.otp
  • authentication.register_verification
  • authentication.password
  • authentication.enable_legal_person

چه زمانی از userActivationModel() استفاده کنیم؟

اگر در flow سفارشی لازم است مستقیم روی مدل activation query بزنید، از helper userActivationModel() استفاده کنید تا کلاس مدل را hardcode نکنید.