كيفية منع تسجيلات تسجيلات متعددة في موقع PHP

StackOverflow https://stackoverflow.com/questions/1727919

  •  19-09-2019
  •  | 
  •  

سؤال

أريد منع تسجيلات تسجيلات متعددة في تطبيق PHP.

أولا، أقوم بإنشاء حالة تسجيل الدخول (نشط، غير نشط) في جدول المستخدم.

عند تعيين سجلات المستخدم في حالة المستخدم على "نشط"، وإذا سجل المستخدم سيتم تعيين الحالة إلى "غير نشط". عند تريس عميل آخر لتسجيل الدخول باستخدام نفس المستخدم، أتحقق من جدول المستخدم. إذا كان المستخدم لا يزال نشطا، فسيتم إرسال تسجيل الدخول إلى المستخدم.

حدثت المشكلة، إذا أغلق المستخدم المتصفح، فيمكن تحديث الحالة في جدول المستخدم لأن المستخدم لم يقر فوق تسجيل الخروج.

هل لديك أي اقتراح حول هذا؟

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

المحلول

(يرجى ملاحظة أنه في حين أن التقنية هنا لا تزال صالحة إلى حد ما؛ لا ينبغي نسخ عينات PHP الحرفية لأن هناك وسيلة أكثر أمانا لإدماج القيم التي توفرها المستخدم في استعلام SQL)


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

أوصي بفعل ما يلي؛

أولا، قم بإنشاء تجزئة لتحديد المستخدم بشكل فريد عند تسجيل الدخول. سأتخيل ذلك sha1 من time() سيكون كافيا لتجنب الاصطدامات. كل ما تختاره، تأكد من أنه متنوع بما فيه الكفاية بحيث يكون لدى مستخدمي المستخدم الآخر فرصة منخفضة بشكل لا يصدق لتلقي نفس التجزئة (على سبيل المثال، لا Hash عنوان IP أو وكيل المستخدم للمستعرض، لأن هذه لا تختلف كافي).

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

نظرا لأننا نستخدم جلسات، فيجب وضع ملف تعريف الارتباط تلقائيا في متصفح المستخدم الذي سيحتوي على معرف فريد يحدد المستخدم بيانات الجلسة الخاصة به. محتويات ملفات تعريف الارتباط ليست ذات اهتمام حقا.

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

علي سبيل المثال:

function authenticateUser($id, $hash, $databaseLink) {
    # SQL
    $sql = 'SELECT EXISTS(
               SELECT 1
               FROM `tbl_users`
               WHERE `id` = \''.mysql_real_escape_string($id).'\'
               AND `hash` = \''.mysql_real_escape_string($hash).'\'
               LIMIT 1
           );';

    # Run Query
    if ($query = mysql_query($sql, $databaseLink)) {
        # Get the first row of the results
        # Assuming 'id' is your primary key, there
        # should only ever be one row anyway.       
        $result = mysql_fetch_row($query);

        # Casting to boolean isn't strictly necessary here
        # its included to indicate the mysql result should
        # only ever been 1 or 0.
        return (bool)($result[0]);
    } else {
        # Query error :(
        return false;
    }
}

ثم، نحن ببساطة نمر authenticateUser() المستخدمين ID, hash (لكل بيانات الجلسة الخاصة بك) و database link (للحصول على اتصال قاعدة بيانات، سيتعين عليك فتحه مسبقا).

لو authenticateUser() عائدات true, ، يتم مصادقة المستخدم. لو false, ، المستخدم ليس أو قاعدة البيانات غير متوفرة أو هناك خطأ SQL.

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

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

نصائح أخرى

إليك حلا لا تتطلب ثابتا الوصول إلى قاعدة البيانات للعمل ...

(والتي ستتجنب شرط التحقق من Session_id () مقابل قيمة قاعدة البيانات في كل مرة تطلبها / تحديث الصفحة أو تخفيف إجهاد DB / Server) ...

1. عند تسجيل الدخول، احصل على Session_id الموجودة مسبقا مخزنة في DB لهذا المستخدم وقم بهذا:

session_id("the pre-existing session id in the database goes here");
session_start();
session_destroy();

2. ثم ابدأ جلسة جديدة وحفظ هذه الجلسة الجديدة_ID إلى قاعدة البيانات، والكتابة فوقها السابقة. سيؤدي ذلك إلى تسجيل الخروج من الجلسة السابقة على هذا المستخدم إذا كان هناك واحد نشط (قم بتسجيل الخروج بشكل فعال الرجل الآخر باستخدام هذا الحساب).

اعطيه محاولة واسمحوا لي أن أعرف إذا كان هذا يفعل الخدعة!

يمكنك تغيير النموذج الخاص بك بحيث يمكن تسجيل الدخول الأكثر أحدث فقط.

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

للمستخدم العادي، يبدو أن الأمور "مجرد عمل". إذا كنت ترغب في منع المستخدمين "غير الطبيعيين" من توزيع بيانات اعتماد تسجيل الدخول الخاصة بهم، يجب أن يكون هذا بمثابة مثبط.

ما يجب عمله هو التحقق مما إذا كانت نشطة في الدقائق القليلة الماضية عند محاولة تسجيل الدخول. يمكن القيام بذلك باستخدام ختم Lastonline ويجب تعيينه في كل طلب صفحة في جدول المستخدم.

إذا لم يتم ذلك مع JavaScript، فيمكنك التحقق، عند تسجيل الدخول، إذا كان المستخدم نشطا في آخر 15 دقيقة. إذا لم يكن بإمكانك تسجيل الدخول كمستخدم جديد.

يمكنك أيضا القيام بذلك مع جافا سكريبت. قم بإجراء مكالمة AJAX التي تنطلق كل دقيقة أو نحو ذلك.

<script>
setInterval(function() {
  // do the ajax call
}, 60000);
</script>

دع هذه المكالمة تذهب إلى برنامج نصي سيقوم بتحرير ختم LastOnline في المستخدم DB. عند محاولة تسجيل الدخول، تحقق من المستخدم DB إذا تجاوز ختم LastOnline الدقيقة ولديك الشيك الخاص بك إذا كنت قد تسجيل الدخول. سيساعد هذا عندما تكون في الصفحة ولكنك غير نشط في آخر 15 دقيقة وأنت لا تريد أن يقوم شخص آخر بتسجيل الدخول.

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

$unique_id = sha1('xzr4'.gethostbyaddr($_SERVER['REMOTE_ADDR']).$random_string.$_SERVER['HTTP_USER_AGENT'].'f8k2');

إذا كان معرف فريد لا يتطابق، فأنت ببساطة تسجيل المستخدم.

استخدام جافا سكريبت جانبي العميل من أجل تتبع المستخدم غير موثوق به.

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

في كل محاولة تسجيل الدخول، إذا الآن () - $ lastlogindate> predefined_timeout، ثم يجب عليك قبول تسجيل الدخول الجديد، وإلا يرفض ذلك.

يشبه هذا الحل prograhammer، ولكن لا يتطلب منك الفوضى مع جلسات التبديل. لا يتطلب منك الوصول إلى قاعدة البيانات على كل صفحة ولا يقوم بإغلاق المستخدم بعد فشل تسجيل الخروج.

أضف حقلا للجلسة إلى جدول المستخدم الخاص بك في قاعدة البيانات.

قم بتعيين معالج الجلسة الافتراضي قبل الاتصال Session_Start () (مطلوب للسطر التالي من التعليمات البرمجية للعمل):

session_set_save_handler(new \SessionHandler());

في كل تسجيل دخول ناجح، استرجع جلسة $ المخزنة من قاعدة البيانات. تدمير الجلسة القديمة مع:

(new \SessionHandler())->destroy($sessionID);

احصل على معرف الجلسة الجديد مع:

$sessionID = session_id();

تخزين معرف الجلسة الجديد إلى قاعدة البيانات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top