بي أتش بي:$_SESSION - ما هي إيجابيات وسلبيات تخزين البيانات المستخدمة مؤقتًا في المتغير $_SESSION

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

  •  09-06-2019
  •  | 
  •  

سؤال

الشيء الوحيد الذي بدأت أفعله كثيرًا مؤخرًا هو استرجاع بعض البيانات في بداية المهمة وتخزينها في $_SESSION['myDataForTheTask'].

يبدو الآن أنه من السهل جدًا القيام بذلك ولكني لا أعرف شيئًا عن الأداء أو المخاطر الأمنية أو ما شابه ذلك باستخدام هذا الأسلوب.هل هذا شيء يتم القيام به بانتظام من قبل المبرمجين ذوي الخبرة الأكبر أم أنه شيء من الهواة؟

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

if (!isset($_SESSION['dataentry']))
{
    $query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=" . mysql_real_escape_string($_GET['wave_id']);
    $result_taskinfo = $db->query($query_taskinfo);
    $row_taskinfo = $result_taskinfo->fetch_row();

        $dataentry = array("pcode" => $row_taskinfo[0], "modules" => $row_taskinfo[1], "data_id" => 0, "wavenum" => $row_taskinfo[2], "prequest" => FALSE, "highlight" => array());

        $_SESSION['dataentry'] = $dataentry;
}
هل كانت مفيدة؟

المحلول

تعد متغيرات الجلسة حقًا إحدى الطرق الوحيدة (وربما الأكثر كفاءة) لإتاحة هذه المتغيرات طوال الوقت الذي يتواجد فيه الزائر على موقع الويب، ولا توجد طريقة حقيقية للمستخدم لتحريرها (بخلاف استغلال في كود، أو في مترجم PHP) بحيث تكون آمنة إلى حد ما.

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

لا يمكنني التفكير في أي طريقة أخرى لتخزين المتغيرات المؤقتة بشكل آمن (حيث يمكن تعديل ملفات تعريف الارتباط بسهولة وسيكون هذا غير مرغوب فيه في معظم الحالات) لذلك سيكون $_SESSION هو الحل الأمثل

نصائح أخرى

آلية $_SESSION تستخدم ملفات تعريف الارتباط.

في حالة Firefox (وربما IE الجديد، لم أتحقق بنفسي) فهذا يعني ذلك تتم مشاركة الجلسة بين علامات التبويب المفتوحة.هذا ليس شيئًا تتوقعه بشكل افتراضي.وهذا يعني أن الجلسة لم تعد "شيئًا خاصًا بنافذة/مستخدم واحد".

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

وهذا أمر غير مريح حقًا، خاصة إذا كنت تقوم بتشفير عميل البريد الإلكتروني أو أي شيء آخر (مثل المتجر الإلكتروني).في هذه الحالة، سيتعين عليك إدارة الجلسات يدويًا أو إدخال مفتاح يتم تجديده باستمرار في عنوان URL أو القيام بشيء آخر.

أستخدم متغير الجلسة طوال الوقت لتخزين المعلومات للمستخدمين.لم أرى أي مشاكل مع الأداء.يتم سحب بيانات الجلسة بناءً على ملف تعريف الارتباط (أو PHPSESSID إذا قمت بإيقاف تشغيل ملفات تعريف الارتباط).لا أرى أن ذلك يشكل خطرًا أمنيًا أكثر من أي مصادقة أخرى تعتمد على ملفات تعريف الارتباط، وربما أكثر أمانًا من تخزين البيانات الفعلية في ملف تعريف ارتباط المستخدمين.

فقط لإعلامك، لديك مشكلة أمنية في عبارة SQL الخاصة بك:

SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".$_GET['wave_id'];

يجب أبدا، أكرر أبدا, ، خذ البيانات المقدمة من المستخدم واستخدمها لتشغيل عبارة SQL دون تنظيفها أولاً.أود أن ألفه بين علامتي اقتباس وأضيف الوظيفة mysql_real_escape_string().وهذا سوف يحميك من معظم الهجمات.لذلك سيبدو خطك كما يلي:

$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id='".mysql_real_escape_string($_GET['wave_id'])."'";

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

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

إذا كنت تعمل على خادمك الخاص، أو في بيئة لا يستطيع أحد فيها التطفل على ملفاتك/ذاكرتك الموجودة على الخادم، فإن بيانات الجلسة تكون آمنة.يتم تخزينها على الخادم ويتم إرسال ملف تعريف الارتباط التعريفي فقط إلى العميل.تكمن المشكلة في إمكانية قيام أشخاص آخرين بخطف ملف تعريف الارتباط وانتحال شخصية شخص آخر بالطبع.إن استخدام HTTPS والتأكد من عدم وضع معرف الجلسة في عناوين URL من شأنه أن يحافظ على أمان المستخدمين من معظم هذه المشكلات.(قد يستمر استخدام XSS لانتزاع ملفات تعريف الارتباط إذا لم تكن حذرًا، راجع مشاركة جيف أتوودز في هذا الشأن أيضاً.)

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

هناك طريقة أخرى لتحسين التحقق من صحة الإدخال وهي إرسال المتغير _GET['wave_id']:

$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".(int)$_GET['wave_id']." LIMIT 1";

أفترض أن wave_id عدد صحيح، وأن هناك إجابة واحدة فقط.

سوف

بعض العيوب الأخرى لاستخدام الجلسات:

  1. $_SESSION ستنتهي صلاحية البيانات بعد ذلك session.gc_maxlifetime ثواني من عدم النشاط.
  2. عليك أن تتذكر الاتصال session_start() لكل برنامج نصي سيستخدم بيانات الجلسة.
  3. قد يمثل توسيع نطاق موقع الويب عن طريق موازنة التحميل على خوادم متعددة مشكلة لأن المستخدم سيحتاج إلى التوجيه إلى نفس الخادم في كل مرة.قم بحل هذه المشكلة باستخدام "الجلسات اللزجة".

يتم تخزين عناصر $_SESSION في الجلسة، والتي يتم الاحتفاظ بها افتراضيًا على القرص.ليست هناك حاجة لإنشاء المصفوفة الخاصة بك وحشوها في إدخال مصفوفة "إدخال البيانات" كما فعلت.يمكنك فقط استخدام $_SESSION['pcode'] و$_SESSION['modules'] وما إلى ذلك.

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

IMO، من المقبول تمامًا تخزين الأشياء في الجلسة.إنها طريقة رائعة لجعل البيانات ثابتة.كما أنها، في كثير من الحالات، أكثر أمانًا من تخزين كل شيء في ملفات تعريف الارتباط.فيما يلي بعض المخاوف:

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

يحتوي Zend Framework على مكتبة مفيدة لإدارة بيانات الجلسة والتي تساعد في انتهاء الصلاحية والأمان (لأشياء مثل رموز التحقق).لديهم أيضًا شرح مفيد للجلسات.يرى http://framework.zend.com/manual/en/zend.session.html

لقد وجدت أن الجلسات مفيدة جدًا، ولكن يجب ملاحظة بعض الأمور:

1) قد يقوم PHP بتخزين جلسات العمل الخاصة بك في مجلد tmp أو دليل آخر قد يكون في متناول المستخدمين الآخرين على الخادم الخاص بك.يمكنك تغيير الدليل الذي تم تخزين الجلسات فيه بالانتقال إلى ملف php.ini.

2) إذا كنت تقوم بإعداد نظام عالي القيمة ويحتاج إلى أمان مشدد للغاية، فقد ترغب في تشفير البيانات قبل إرسالها إلى الجلسة، وفك تشفيرها لاستخدامها.ملحوظة:قد يؤدي هذا إلى إنشاء الكثير من الحمل اعتمادًا على سعة حركة المرور/الخادم لديك.

3) لقد وجدت أن session_destroy();إذا لم يحذف الجلسة على الفور، فلا يزال يتعين عليك الانتظار حتى يقوم جامع البيانات المهملة PHP بتنظيف الجلسات.يمكنك تغيير وتيرة تشغيل أداة تجميع البيانات المهملة في ملف php.ini.ولكن لا يزال لا يبدو موثوقًا جدًا، مزيد من المعلومات http://www.captain.at/howto-php-sessions.php

قد ترغب في التفكير في مدى أهمية هذا الأمر؟

أي.راجع فقرة "التواصل مع عديمي الجنسية" في "مقدمة موجزة عن REST"...

"تقوم REST بتفويض أن تتحول الدولة إلى حالة موارد ، أو الاحتفاظ بها على العميل.وبعبارة أخرى ، لا ينبغي أن يضطر الخادم إلى الاحتفاظ ببعض حالة الاتصال لأي من العملاء الذين يتواصلون معهم إلى ما هو أبعد من طلب واحد. "

(أو أي من الروابط الأخرى على ويكيبيديا لـ استراحة)

لذا، في حالتك، يعد "wave_id" مصدرًا معقولاً لـ GET، ولكن هل تريد حقًا تخزينه في الجلسة؟بالتاكيد com.memcached هو الحل الخاص بك للتخزين المؤقت للكائن المورد؟

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

مثل أي شيء آخر، فقط كن حذرًا من أنك تقوم دائمًا بتطهير إدخال المستخدم، خاصة إذا كنت تضع إدخال المستخدم في المتغير $_SESSION، ثم تستخدم هذا المتغير لاحقًا في استعلام SQL.

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

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

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

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