سؤال

دعونا نقول لدي SQL مثل هذا أن يتحقق المستخدم تسجيل الدخول:

SELECT * FROM users 
WHERE username='test@example.com', password='abc123', expire_date>=NOW();

هل هناك طريقة في SQL لتحديد على وجه التحديد حيث الظروف التي تفشل ، دون الحاجة إلى فصل كل حالة إلى جانبها الاستعلام اختبار على حدة ؟

في هذا المثال سوف تسمح للمطور للمستخدمين اقول بالضبط السبب في محاولة فشل تسجيل الدخول.

لأغراض بلدي أنا باستخدام PHP/MySQL.

هل كانت مفيدة؟

المحلول 5

هنا هو ما جئت به:

SELECT
  IF(mem_username='test@example.com','true','Error: Bad Username') AS mem_username,
  IF(mem_password ='abc123','true','Error: Bad Password') AS mem_password'
FROM MEMBERS
WHERE mem_username='test@example.com' AND mem_password='abc123'

بهذه الطريقة يمكنني الكشف عن رمز رسائل الخطأ ومن ثم عرض لهم عند الضرورة.

ملاحظة: لكم جميعا نقلا عن المخاوف الأمنية مع رمز المثال, شكرا لك على اهتمامك.ولكن هذا ليس هو الإنتاج الحقيقي رمز هذا كان مجرد مثال بسيط لتوضيح السؤال كان.فمن الواضح تماما أنه يجب أن لا تخزن كلمات المرور في نص واضح ، و التي يجب أن لا تعطي للمستخدمين تفاصيل عن سبب فشل تسجيل الدخول.

نصائح أخرى

حسنا، هناك شيء واحد يمكن القيام به هو تغيير الاستعلام الخاص بك بحيث يطابق فقط على اسم المستخدم. ثم في رمز التحقق من كلمة المرور وتاريخ انتهاء الصلاحية، والعودة الأخطاء المناسبة.

وأيضا، وآمل المثال الاستعلام الخاص بك هو تبسيط. بالتأكيد يجب أن تكون التمليح / تشفير / تجزئة كلمات السر الخاصة بك، ويجب أن تشمل شيء يحد من عدد من المحاولات الفاشلة في إطار زمني معين، الخ ...

وبقدر السؤال الفعلي (على عكس النتائج التي تبحث عن)، وليس هناك طريقة للحصول على تلك المعلومات من شرط مكان. سيكون الأقرب يمكن أن تفعله أن يكون شيئا مثل:

SELECT *,
    CASE WHEN Password = 'asdf' THEN 1 ELSE 0 END AS IsPasswordMatch,
    CASE WHEN Expiration >= NOW() THEN 1 ELSE 0 END AS IsActiveAccount
FROM Users
WHERE Username = 'user'

في الخلية يمكنك وضع التعبيرات المنطقية في القائمة المختارة. التعبيرات المنطقية تقييم إلى عدد صحيح 1 عندما الحقيقية، أو عدد صحيح 0 عندما كاذبة.

SELECT password = 'abc123' AS is_authenticated,
       expire_date >= NOW() AS is_not_expired
FROM users
WHERE username='test@example.com';

<قوية> ملاحظة: إذا كنت بحاجة إلى كتابة استعلام الذي يعمل على ماركات أخرى من RDBMS، أن نضع في اعتبارنا هذا استخدام تعبيرات منطقية هو غير قياسي. استخدم بناء الجملة CASE التي نشرت الناس الآخرين.

وPS: هذا هو الظل من سؤالك، ولكن أنا أحثكم على عدم تخزين كلمات المرور في نص عادي. تخزين تجزئة خلاصة كلمة المرور المملحة. انظر كيف تساعد كلمة ملح ضد هجوم الجدول قوس قزح؟

لا, حيث شرط تطبيقها الحي ، و تقنيات مختلفة تستخدم ذلك أنه ليس كل الصفوف يجب أن يتم مسحها ضوئيا.أيضا, كيف يمكنك أن تعرف أي صف كان المنشود ؟

بالإضافة إلى ذلك, ربما كنت لا تريد أن تخبر المستخدم كثيرا عن سبب محاولة تسجيل الدخول الفاشلة.يقول الكثير من يسمح يستغل مثل حساب التعدين وكلمة المرور الهجمات.

تحرير إذا كنت حقا ترغب في عرض هذا المستخدم الخاص بك ، ثم تقسيم المنطق الخاص بك إلى أجزاء مختلفة:

  1. التحقق من الهوية
    العمل:جلب المقابلة المستخدم الصف من قاعدة البيانات
    النتيجة:
    • إذا كان لا يوجد مثل هذا الصف موجودة => الحساب غير صالح
    • إذا كان يتم إرجاع صف, انتقل إلى الخطوة 2.
  2. التحقق من صحة بيانات اعتماد
    العمل:التحقق من بيانات الاعتماد المخزنة (كلمة المرور ، تجزئة كلمة المرور أو كلمة السر المشفرة) ضد الموردة كلمة المرور تعامل بنفس الطريقة الاعتماد المخزنة.
    النتيجة:
    • لا تطابق => كلمة المرور غير صالحة / الاعتماد
    • المباراة => الناجحة محاولة تسجيل الدخول
  3. المستخدم تسجيل الدخول
    العمل:إضافة البيانات إلى الدورة.... الخ

وربما كنت بحاجة فقط لفصل أجزاء من بند فيها مع 'AND'

SELECT * FROM users 
WHERE username='test@example.com'
   And password='abc123'
   And expire_date>=NOW();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top