14 KiB
14 KiB
تحليل تدفق الراكب (Siro Rider)
من Flutter إلى PHP Backend — تسجيل + دخول + OTP
1. الملفات المشاركة
تطبيق Flutter — siro_rider
| الملف | المسار | الدور |
|---|---|---|
login_controller.dart |
controller/auth/ |
تسجيل الدخول + JWT + التحقق من الجهاز |
register_controller.dart |
controller/auth/ |
إنشاء حساب جديد + OTP + SMS |
otp_controller.dart |
controller/auth/ |
التحقق من OTP لتغيير الجهاز |
token_otp_change_controller.dart |
controller/auth/ |
إدارة OTP لتغيير التوكن |
verify_email_controller.dart |
controller/auth/ |
التحقق من الإيميل |
crud.dart |
controller/functions/ |
HTTP client مع JWT + NetGuard |
sms_controller.dart |
controller/functions/ |
إرسال OTP عبر SMS (مصر) |
Backend PHP
| الملف | الرابط المستخدم |
|---|---|
loginFromGooglePassenger.php |
loginFromGooglePassenger |
loginFirstTime.php |
loginFirstTime |
login.php |
loginJwtRider |
auth/signup.php |
signUp |
auth/checkPhoneNumberISVerfiedPassenger.php |
checkPhoneNumberISVerfiedPassenger |
auth/otp/request.php |
sendVerifyOtpMessage |
auth/otp/verify.php |
verifyOtpPassenger |
auth/verifyEmail.php |
verifyEmail |
2. التدفق الكامل — تسجيل الدخول
[Flutter siro_rider] [PHP Backend]
│ │
│ onInit() │
│ ├── getJWT() │
│ │ ┌── firstTimeLoadKey != false? │
│ │ ├── نعم → loginFirstTime.php │
│ │ │ POST { id, password, aud, │
│ │ │ fingerPrint } │
│ │ │ ─────────────────────────────────>│
│ │ │ ← Registration JWT (150s) │
│ │ │ │
│ │ └── لا → login.php (تجديد) │
│ │ POST { id, fingerPrint, aud } │
│ │ ─────────────────────────────────>│
│ │ ← Access JWT (3600s) │
│ │ │
│ ├── isTokenValid() │
│ │ ← يتحقق من exp يدوياً (بدون مكتبة) │
│ │ │
│ │ │
│ loginUsingCredentials(passengerID, email) │
│ GET loginFromGooglePassenger.php │
│ ?email=X&id=Y&platform=Z&appName=W │
│ ─────────────────────────────────────────>│
│ │ 【connect.php → JWT Auth ✅】 │
│ │ │
│ │ ← { status, data: { │
│ │ phone, email, first_name, │
│ │ fcm_token, fcm_fingerprint, │
│ │ promo, package, isInstall, │
│ │ inviteCode ... } } │
│ │ │
│ ├── يخزّن البيانات في GetStorage │
│ ├── يفحص verified = '1'? │
│ │ └── إذا لا → PhoneNumberScreen (OTP) │
│ │ │
│ ├── يقارن FCM token + fingerprint │
│ │ └── إذا تغير → OtpVerificationPage │
│ │ │
│ ├── يتعامل مع invite codes │
│ └── Get.offAll(MapPagePassenger) │
│ │
3. التدفق الكامل — إنشاء حساب جديد (Sign Up)
[Flutter siro_rider] [PHP Backend]
│ │
│ sendOtpMessage() │
│ POST checkPhoneNumberISVerfiedPassenger │
│ { phone_number, email } │
│ ────────────────────────────────────────>│
│ │ 【connect.php → JWT Auth ✅】 │
│ │ │
│ │ ← is_verified=1? │
│ │ │
│ ├── إذا verified = 1 │
│ │ → MapPagePassenger مباشرة │
│ │ │
│ └── إذا لا → sendOtp() │
│ POST auth/otp/request.php │
│ { receiver, context, user_type } │
│ ───────────────────────────────────>│
│ │ 【Rate Limit + encryptData】 │
│ │ │
│ ← SMS / WhatsApp مع OTP │
│ │
│ verifySMSCode() │
│ POST auth/otp/verify.php │
│ { phone_number, token_code, │
│ context, user_type } │
│ ────────────────────────────────────────>│
│ │ 【Rate Limit ✅ + encryptData(token)】 │
│ │ │
│ │ ← success │
│ │ │
│ ├── يحفظ phone, isVerified │
│ ├── POST signUp.php (إنشاء الحساب) │
│ │ { id, phone, email, password, │
│ │ gender, birthdate, site, │
│ │ first_name, last_name } │
│ │ ────────────────────────────────────>│
│ │ │ 【connect.php → JWT Auth ✅】 │
│ │ │ │
│ └── loginUsingCredentials() → الدخول │
│ │
4. تدفق OTP — كامل مع التشفير
[Flutter] [auth/otp/request.php] [auth/otp/verify.php]
│ │ │
│ POST /auth/otp/request.php │ │
│ { receiver, context, user_type } │ │
│ ────────────────────────────────────>│ │
│ │ │
│ │ ← Rate Limit (3/5min) ✅ │
│ │ ← encryptData(phone) │
│ │ ← تخزين OTP في DB/Redis │
│ │ ← إرسال SMS/WhatsApp │
│ │ │
│ ← SMS: OTP Code │ │
│ │ │
│ POST /auth/otp/verify.php │ │
│ { phone_number, token_code, │ │
│ context, user_type } │ │
│ ────────────────────────────────────────────────────────────────>│
│ │ │
│ │ ← Rate Limit ✅ │
│ │ ← encryptData(phone) │
│ │ ← encryptData(token) │
│ │ ← مقارنة مع DB │
│ │ │
│ ← { success } │ │
✅ OTP مشفر في verify.php:
// السطر 67
$encryptedToken = $encryptionHelper->encryptData($token_code);
5. ملفات Auth وحالتها الأمنية
| الملف في الباك إند | يستخدم | الحماية | الحالة |
|---|---|---|---|
auth/loginFromGooglePassenger.php |
connect.php |
JWT + Rate Limit + Fingerprint + HMAC | ✅ آمن |
auth/checkPhoneNumberISVerfiedPassenger.php |
connect.php |
JWT + Rate Limit | ✅ آمن |
auth/signup.php |
connect.php |
JWT + Rate Limit | ✅ آمن |
loginFirstTime.php |
bootstrap.php |
Password + Rate Limit (3/ساعة) + Pepper | ✅ آمن |
login.php |
bootstrap.php |
Fingerprint + Rate Limit + Revocation | ✅ آمن |
auth/otp/request.php |
bootstrap.php |
Rate Limit + encryptData | ✅ آمن |
auth/otp/verify.php |
bootstrap.php |
Rate Limit ✅ + encryptData | ✅ آمن |
auth/verifyEmail.php |
connect.php |
JWT + Rate Limit | ✅ آمن |
6. البيانات المُرسلة والمستقبلة
📤 من Flutter إلى PHP
| المعلومة | التنظيف | التشفير |
|---|---|---|
✅ filterRequest() |
✅ encryptData() قبل البحث في DB |
|
| phone | ✅ filterRequest() |
✅ encryptData() قبل التخزين |
| id (passengerID) | ✅ filterRequest() |
لا تشفير (رقم تعريف فقط) |
| fingerprint | ✅ filterRequest() |
✅ SHA-256 مع Pepper |
| token_code (OTP) | ✅ filterRequest() |
✅ encryptData() في verify.php |
| password | ✅ filterRequest() |
✅ password_hash() في DB |
📥 من PHP إلى Flutter
| المعلومة | هل هي آمنة؟ | ملاحظة |
|---|---|---|
| JWT | ✅ مخزَّن في GetStorage + SecureStorage | ⚠️ GetStorage غير مشفر |
| phone | ✅ مفكوك تشفيره للعرض فقط | |
| ✅ مفكوك تشفيره للعرض فقط | ||
| first_name, last_name | ✅ مفكوك تشفيرهما | |
| fcm_token | ✅ مفكوك تشفيره | 🔴 حساس — FCM token يسمح بإرسال إشعارات |
| fcm_fingerprint | ✅ يُرسل للمقارنة | |
| promo, package, inviteCode | ✅ غير حساسة | |
| isVerified | ✅ boolean |
7. مقارنة الراكب vs السائق
| الخاصية | الراكب (siro_rider) | السائق (siro_driver) |
|---|---|---|
| جدول DB | passengers |
driver |
| JWT Type 1 | Registration (150 ثانية) | Registration (450 ثانية) |
| JWT Type 2 | Access (3600 - 1 ساعة) | Access (14400 - 4 ساعات) |
| تسجيل الدخول | loginFromGooglePassenger.php عبر connect.php |
loginFromGoogle.php عبر connect.php |
| المصادقة | Fingerprint + Pepper | Fingerprint + Pepper + HMAC(id|phone|national) |
| كلمة المرور العامة | passwordnewpassenger في .env |
passwordnewpassenger في .env |
| OTP | auth/otp/verify.php (user_type=passenger) |
auth/otp/verify.php (user_type=driver) |
| فحص الجهاز | يقارن FCM token + fingerprint | يقارن driver token + fingerprint |
| Rate Limiting OTP | ✅ مُضاف (request + verify) | ✅ مُضاف (request + verify) |
| IsVerified شرط | verified = '1' إجباري |
is_verified = '1' إجباري |
8. الملخص النهائي
| البند | النتيجة |
|---|---|
| التدفق العام | ✅ صحيح — Flutter → connect.php (JWT) → معالجة → رد |
| connect.php يحمي | ✅ loginFromGoogle, checkPhone, signup, verifyEmail |
| JWT + Fingerprint | ✅ Registration (150s) → Access (1h) مع Pepper |
| Token Revocation | ✅ عبر Redis في login.php |
| OTP مشفر | ✅ encryptData(token_code) في verify.php |
| Rate Limiting | ✅ على login (5/دقيقة)، OTP request (3/5min)، OTP verify (3/5min) |
| كشف تغيير الجهاز | ✅ يقارن FCM token + fingerprint → OTP إذا اختلف |
| Timing Attack | ✅ usleep() في login.php |
| تشفير DB | ✅ جميع PII مشفرة |
⚠️ ملاحظة واحدة
يُستخدم GetStorage لتخزين JWT، وهو غير مشفر. لكنه يُستخدم مع FlutterSecureStorage أيضاً. يُفضل الاعتماد على FlutterSecureStorage فقط للـ JWT.
✅ الخلاصة
تدفق الراكب (Siro Rider) صحيح أمنياً وإجرائياً بالكامل.
- جميع ملفات Auth محمية عبر
connect.phpالحديث (JWT + Rate Limit) - OTP مشفر قبل التخزين والمقارنة
- JWT مرتبط بالجهاز عبر Fingerprint + Pepper
- كشف تغيير الجهاز عبر FCM + Fingerprint
- Rate Limiting على جميع نقاط الدخول