שכחו משחזור סיסמה. הרשאת SMS באמצעות מספר טלפון פותרת את הבעיה: הזינו מספר, קבלו קוד OTP, והיכנסו. אנו מיישמים תהליך זה במפתח מלא — מאינטגרציית ספק ועד ממשק קדמי עם טיימר. זה סטנדרטי למסחר אלקטרוני, משלוחים ופינטק ברוסיה: ללא סיסמאות, רק מספר מאומת.
סקירה כללית של הרשאת OTP
OTP (סיסמה חד-פעמית) היא סיסמה חד-פעמית הנשלחת באמצעות SMS ותקפה ל-5 דקות. זוהי חלופה לאימות סיסמה: המשתמש מזין מספר טלפון, מקבל קוד, ונכנס מיד. ללא סיסמאות, ללא דליפות האש. בהתבסס על הנתונים שלנו, זמן הכניסה מתקצר בחצי בהשוואה לשיטת הסיסמה. הרשאת OTP חוסכת בתקציב: ההמרה עלתה ב-25% בפרויקט אחד, ובקשות תמיכה לאיפוס סיסמה ירדו ב-60% בפרויקט אחר.
ספקי SMS לרוסיה וחבר העמים
| ספק | תכונות |
|---|---|
| SMSC.ru | פופולרי, יש לו HTTP API ו-SMPP |
| SMS.ru | API פשוט, אספקה טובה |
| Exolve (MTS) | ברמת ספק, מספרים וירטואליים |
| Infobip | בינלאומי, יקר, אמין |
| Twilio | בינלאומי, לא זמין ברוסיה ללא VPN |
| Firebase SMS | ליישומים ניידים, לא לאינטרנט |
אבטחה ואמינות של הרשאת SMS
סיסמאות הן מטרד: משתמשים קובעים שילובים חלשים, חוזרים עליהם בין אתרים, ושומרים אותם בהערות. קוד OTP חי 5 דקות, מקושר למכשיר, ולא ניתן לגנוב אותו ממכשיר אחר. אנו משפרים את ההגנה עם:
- אחסון האש של הקוד ב-Redis, לא הקוד עצמו.
- הגבלת קצב: לא יותר מ-3 SMS בשעה ממספר אחד, ניסיון אימות אחד לדקה.
- מגבלת ניסיונות: 3 כישלונות — חסימת המספר ל-5 דקות.
הבטחת אספקת SMS
ללא אספקת קוד, ההרשאה לא עובדת. לכן, אנו מבטיחים אספקה באמצעות ניטור יתרת הספק וגיבוי לספק חלופי, נורמליזציה של מספרים באמצעות ספריית libphonenumber (פורמט E.164), וטיפול בשגיאות API של הספק. אם התשובה היא error, אנו מתעדים אותה ומודיעים למנהל המערכת. בנוסף, אנו מגדירים ניסיון חוזר אוטומטי לאחר 60 שניות והודעה למשתמש. אנו מבטיחים אספקה של 99.9% עם ספק גיבוי.
יישום שלב אחר שלב: 5 שלבים
- שירות OTP: יצירת קוד בן 6 ספרות, אחסון האש SHA-256 שלו ב-Redis עם TTL של 5 דקות.
- אינטגרציית ספק SMS: חיבור ל-SMSC.ru או SMS.ru באמצעות HTTP API וטיפול בתשובות.
-
נקודות קצה של API: יצירת
POST /auth/phone/send-code { phone: "+79001234567" } → валидация номера → генерация OTP → сохранение hash(OTP) в Redis с TTL 5 мин → отправка SMS → ответ: { expires_in: 300 }(עם הגבלת קצב) ו-POST /auth/phone/verify { phone: "...", code: "123456" } → проверка OTP из Redis → создание/поиск пользователя → выдача сессии или JWT. - טופס קדמי: בניית טופס עם שדה מספר, שדה קוד, טיימר שליחה חוזרת, ושליחה אוטומטית.
- טיפול במקרי קצה: בדיקה עם מספרים לא חוקיים, OTP שפג תוקפו, ועומס גבוה (1000 בקשות במקביל).
ארכיטקטורה ותהליך יישום
שלב 1: שליחת קוד
POST /auth/phone/send-code { phone: "+79001234567" } → валидация номера → генерация OTP → сохранение hash(OTP) в Redis с TTL 5 мин → отправка SMS → ответ: { expires_in: 300 } שלב 2: אימות
POST /auth/phone/verify { phone: "...", code: "123456" } → проверка OTP из Redis → создание/поиск пользователя → выдача сессии или JWT יצירת ואחסון OTP
class PhoneOtpService {
public function sendOtp(string $phone): int {
$this->checkRateLimit($phone);
$code = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);
// Хранить хэш, не сам код
Cache::put(
"phone_otp:{$phone}",
[
'hash' => hash('sha256', $code),
'attempts' => 0,
],
now()->addMinutes(5)
);
$this->smsProvider->send($phone, "Ваш код: {$code}");
return 300; // expires_in seconds
}
public function verifyOtp(string $phone, string $code): bool {
$data = Cache::get("phone_otp:{$phone}");
if (!$data) {
throw new OtpExpiredException();
}
// Ограничение попыток
if ($data['attempts'] >= 3) {
Cache::forget("phone_otp:{$phone}");
throw new OtpAttemptsExceededException();
}
if (!hash_equals($data['hash'], hash('sha256', $code))) {
Cache::put("phone_otp:{$phone}", array_merge($data, [
'attempts' => $data['attempts'] + 1,
]), now()->addMinutes(5));
return false;
}
Cache::forget("phone_otp:{$phone}");
return true;
}
} הגבלת קצב
// Не более 3 SMS в час с одного номера
RateLimiter::for('sms-otp', function (Request $request) {
return [
Limit::perHour(3)->by('phone:' . $request->phone),
Limit::perMinute(1)->by('phone:' . $request->phone),
];
}); נורמליזציה של מספר טלפון
use libphonenumber\PhoneNumberUtil;
$phoneUtil = PhoneNumberUtil::getInstance();
$parsed = $phoneUtil->parse($rawPhone, 'RU');
if (!$phoneUtil->isValidNumber($parsed)) {
throw new InvalidPhoneNumberException();
}
$normalized = $phoneUtil->format($parsed, \libphonenumber\PhoneNumberFormat::E164); // +79001234567
הספרייה class PhoneOtpService { public function sendOtp(string $phone): int { $this->checkRateLimit($phone); $code = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT); // Хранить хэш, не сам код Cache::put( "phone_otp:{$phone}", [ 'hash' => hash('sha256', $code), 'attempts' => 0, ], now()->addMinutes(5) ); $this->smsProvider->send($phone, "Ваш код: {$code}"); return 300; // expires_in seconds } public function verifyOtp(string $phone, string $code): bool { $data = Cache::get("phone_otp:{$phone}"); if (!$data) { throw new OtpExpiredException(); } // Ограничение попыток if ($data['attempts'] >= 3) { Cache::forget("phone_otp:{$phone}"); throw new OtpAttemptsExceededException(); } if (!hash_equals($data['hash'], hash('sha256', $code))) { Cache::put("phone_otp:{$phone}", array_merge($data, [ 'attempts' => $data['attempts'] + 1, ]), now()->addMinutes(5)); return false; } Cache::forget("phone_otp:{$phone}"); return true; } } היא גרסת PHP של libphonenumber של Google.
יצירת משתמש בכניסה ראשונה
לאחר אימות קוד מוצלח, המשתמש נוצר במערכת אם הוא עדיין לא קיים. השדה // Не более 3 SMS в час с одного номера RateLimiter::for('sms-otp', function (Request $request) { return [ Limit::perHour(3)->by('phone:' . $request->phone), Limit::perMinute(1)->by('phone:' . $request->phone), ]; }); הוא המזהה הייחודי. שדות נוספים (שם, דוא"ל) נדרשים לאחר הכניסה הראשונה לפי הצורך.
מה כלול בפיתוח במפתח מלא?
- שירות OTP (יצירה, האשה, הגבלת קצב).
- אינטגרציה עם ספק SMS נבחר.
- נקודות קצה של API לשליחה ואימות.
- טופס קדמי עם טיימר ושליחה אוטומטית.
- תיעוד וכיסוי בדיקות (מקרי קצה, עומס).
לוח זמנים
| שלב | זמן |
|---|---|
| שירות OTP + Redis | יום אחד |
| אינטגרציית ספק SMS | חצי יום |
| נקודות קצה של API + הגבלת קצב | חצי יום |
| תהליך קדמי (טופס + טיימר) | יום אחד |
| בדיקות + מקרי קצה | יום אחד |
סה"כ: 4–5 ימי עבודה.
כיצד אנו בודקים את אמינות ההרשאה?
לפני המסירה, אנו מריצים תרחיש עומס: 1000 בקשות במקביל לשליחת קוד, בודקים הגבלת קצב, מדמים מספרים לא חוקיים ו-OTP שפג תוקפו. כל זה מכוסה בבדיקות אוטומטיות. טעויות אופייניות: לא מתחשבים באזור זמן עבור TTL של OTP, שמירת מספר ללא אזור. אנו מטפלים בכל מקרי הקצה.
הרשאת SMS באמצעות מספר טלפון מהירה פי 2 מכניסת סיסמה וזולה פי 3 לתחזוקה. צרו קשר — נעריך את הפרויקט שלכם תוך שעה. הזמינו יישום במפתח מלא כבר עכשיו. קבלו ייעוץ על יישום הרשאת SMS.
מקור: ניתוח של למעלה מ-50 פרויקטים עם הרשאת SMS במשך מספר שנים.







