คอมพิวเตอร์ Windows อินเทอร์เน็ต

เซสชั่น คำอธิบายโดยละเอียดของการทำงานและคำอธิบายของกลไก การรักษาความปลอดภัย ID เซสชันใน PHP องค์กร inurl สมุดเยี่ยมชม php phpsessid

เซสชันใน PHP หรือวิธีการบันทึกข้อมูลเกี่ยวกับผู้ใช้หรือลูกค้าที่เข้าสู่ไซต์เมื่อนำทางระหว่างหน้าของไซต์โดยไม่ยาก บทเรียนมีความสำคัญมาก เกี่ยวข้องกับการสร้างไซต์ 95%

เซสชันใน php . คืออะไร

เซสชันใช้เพื่อเก็บข้อมูลเกี่ยวกับข้อมูลชั่วคราว (เช่น ที่ผู้ใช้เข้าสู่ไซต์) เมื่อนำทางระหว่างหน้าต่างๆ ของไซต์เดียวกัน เมื่อใช้เซสชัน ข้อมูลจะถูกบันทึกในไฟล์ชั่วคราวบนเซิร์ฟเวอร์
ส่วนใหญ่มักจะใช้เซสชัน (และคุกกี้ด้วย) เมื่อสร้างร้านค้าออนไลน์ ฟอรัม กระดานข้อความ สังคมออนไลน์, บล็อกและแหล่งข้อมูลอื่นๆ ความสะดวกของระบบเซสชั่นประกอบด้วยการจัดเก็บข้อมูลชั่วคราวของผู้ใช้ / ลูกค้าที่เข้าสู่ระบบซึ่งข้อมูลที่สามารถเข้าถึงได้อย่างรวดเร็วในช่วงเวลาหนึ่ง เซสชั่นมีวันหมดอายุตามธรรมชาติ - จนกว่าเบราว์เซอร์จะปิด หากคุณปิดเฉพาะเพจ เมื่อคุณเปิดไซต์ ข้อมูลเกี่ยวกับผู้ใช้ / ผู้ซื้อจะยังปรากฏอยู่

ตรรกะของเซสชัน

เซสชัน (หรือเซสชัน) เป็นการจัดเก็บข้อมูลชั่วคราวชนิดหนึ่ง ฉันเตือนคุณทันทีว่ามันคุ้มค่าที่จะบันทึกข้อมูลจำนวนเล็กน้อย ตัวอย่างเช่น การเข้าสู่ระบบและรหัสผ่านของผู้ใช้ที่เข้าสู่ระบบหรือหมายเลขซีเรียลในฐานข้อมูล

ตัวอย่างผลงาน
1. ผู้ใช้ป้อนชื่อผู้ใช้และรหัสผ่านและเข้าสู่เว็บไซต์
2. ข้อมูลที่มีการเข้าสู่ระบบและรหัสผ่านจะถูกบันทึกไว้ในเซสชันของหน้าใดหน้าหนึ่งของเว็บไซต์:

ไฟล์ index.php

Session_start (); // แต่ละไฟล์ที่คุณต้องการใช้ข้อมูลเซสชันต้องมีคำสั่ง "start session" ที่จุดเริ่มต้นของโค้ด

$ เข้าสู่ระบบ = "ผู้ดูแลระบบ";
$ รหัสผ่าน = "ผ่าน";
$ _SESSION ["เข้าสู่ระบบ"] = $ เข้าสู่ระบบ; // บันทึกตัวแปรที่มีล็อกอิน
$ _SESSION ["รหัสผ่าน"] = $ รหัสผ่าน; // บันทึกตัวแปรที่มีรหัสผ่าน

3. เมื่อคุณไปที่หน้าอื่นของไซต์ ข้อมูลนี้จะยังสามารถใช้ได้:

ไฟล์ example.php(หรือหน้าอื่นๆ)

Echo "การเข้าสู่ระบบของคุณ" $ _ SESSION ["login"]; // จะแสดง "เข้าสู่ระบบของคุณคือผู้ดูแลระบบ" แม้ว่าเราจะไม่ได้บันทึกข้อมูลในหน้านี้!
ดูมันง่าย!

4. หากคุณต้องการล้างข้อมูลเซสชันก็เพียงพอแล้ว:

ไฟล์ example.php

Session_start (); // "เริ่มเซสชัน" อีกครั้ง

ยกเลิกการตั้งค่า ($ _ SESSION ["เข้าสู่ระบบ"]); // นี่คือวิธีการยกเลิกการลงทะเบียนหรือ "ทำลาย" ตัวแปร
echo "การเข้าสู่ระบบของคุณ" $ _ SESSION ["login"]; // จะแสดง "การเข้าสู่ระบบของคุณ" เนื่องจากเราทำลายมันในบรรทัดสุดท้าย จึงไม่มีข้อมูลเช่นกัน

Session_destroy (); // ทำลายเซสชั่น ข้อมูลทั้งหมดรวมถึง $ _SESSION ["password"] หายไป เมื่อได้รับการร้องขอข้อผิดพลาดจะปรากฏขึ้น
โดยทั่วไป การโอนดังกล่าวจะคล้ายกับ วิธีโพสต์แต่มีเพียงคุณเท่านั้นที่ไม่ต้องเขียนโค้ดที่ไม่จำเป็นอีกต่อไป และข้อมูลทั้งหมดที่ถ่ายโอนจากหน้าหนึ่งไปยังอีกหน้าหนึ่งจะถูกเก็บไว้ในไฟล์ชั่วคราวบนเซิร์ฟเวอร์ อีกครั้ง เซสชันควรมีข้อมูลจำนวนเล็กน้อย ดังนั้นจึงเหมาะสำหรับการจัดเก็บชื่อผู้ใช้/รหัสผ่าน ตะกร้าสินค้า และไดรฟ์ข้อมูลขนาดเล็กอื่นๆ

การส่งค่าหรืออาร์เรย์โดยใช้เซสชัน PHP

ในเซสชั่น คุณไม่เพียงแต่เขียนสตริงได้เท่านั้น แต่ยังเขียนอาร์เรย์ของข้อมูลได้อีกด้วย อย่าหักโหมจนเกินไปกับขนาดของอาร์เรย์ เนื่องจากสิ่งเหล่านี้จะส่งผลต่อประสิทธิภาพการทำงานและพื้นที่ว่างบนเซิร์ฟเวอร์

เราใช้บางอย่างอีกครั้ง หน้าแรก index.php

Session_start ();

$ r = อาร์เรย์ ("หนึ่ง", "สอง", "สาม");

$ _SESSION ["arr"] = $ r;

ไปยังหน้าที่แสดงทุกอย่าง
เราบันทึกข้อมูลในเซสชั่นและไปตามลิงก์ไปยังหน้าอื่น ซึ่งเราจะแสดงข้อมูลทั้งหมด

ผู้รับไฟล์ หน้า test.phpที่เราเปิดอาร์เรย์

Session_start ();
print_r ($ _ SESSION ["arr"]);
// จะออก
/*
Array
=> หนึ่ง
=> สอง
=> สาม
*/
?>
คุณอาจต้องการทบทวนบทแนะนำเกี่ยวกับ โดยทั่วไปแล้ว ทุกอย่างควรมีความชัดเจน

ฟังก์ชันอื่นๆ สำหรับการทำงานกับเซสชัน

session_unregister (สตริง)- เซสชั่นลืมค่าของตัวแปรส่วนกลางที่ระบุ
session_destroy ()- เซสชันถูกทำลาย (เช่น หากผู้ใช้ออกจากระบบโดยการกดปุ่มออกจากระบบ)
session_set_cookie_params (อายุการใช้งาน int [, เส้นทางสตริง [, โดเมนสตริง]])- เมื่อใช้ฟังก์ชันนี้ คุณสามารถกำหนดระยะเวลาที่เซสชันจะใช้งานได้โดยการตั้งค่า unix_timestamp ซึ่งจะกำหนดเวลาการตายของเซสชัน

รายการฟังก์ชันสำหรับการทำงานกับเซสชัน (เซสชัน) ใน php
session_cache_expire - ส่งคืนการหมดอายุของแคชปัจจุบัน
session_cache_limiter - รับและ / หรือตั้งค่าขีด จำกัด แคชปัจจุบัน
session_commit - นามแฝงสำหรับ session_write_close ()
session_decode - ถอดรหัสข้อมูลเซสชันจาก string
session_destroy - ทำลายข้อมูลทั้งหมดที่ลงทะเบียนสำหรับ session
session_encode - เข้ารหัสข้อมูลเซสชันปัจจุบันเป็นสตริง
session_get_cookie_params - รับพารามิเตอร์คุกกี้ของเซสชัน
session_id - รับและ / หรือตั้งค่า ID เซสชันปัจจุบัน
session_is_registered - กำหนดว่าตัวแปรถูกลงทะเบียนใน session . หรือไม่
session_module_name - รับและ / หรือติดตั้งโมดูลสำหรับ session ปัจจุบัน
session_name - รับและ / หรือตั้งชื่อของ session ปัจจุบัน
session_regenerate_id - แก้ไขรหัสเซสชันปัจจุบันด้วยรหัสที่สร้างขึ้นใหม่
session_register - ลงทะเบียนตัวแปรตั้งแต่หนึ่งตัวขึ้นไปสำหรับ session ปัจจุบัน
session_save_path - รับและ / หรือกำหนดเส้นทางเพื่อบันทึกเซสชันปัจจุบัน
session_set_cookie_params - ตั้งค่าพารามิเตอร์คุกกี้ของเซสชัน
session_set_save_handler - ตั้งค่าฟังก์ชั่นการจัดเก็บเซสชันระดับผู้ใช้
session_start - เริ่มต้นข้อมูลเซสชัน
session_unregister - ยกเลิกการลงทะเบียนตัวแปรจาก session ปัจจุบัน
session_unset - เผยแพร่ตัวแปรเซสชันทั้งหมด
session_write_close - เขียนข้อมูลเซสชันและสิ้นสุด session

ตัวอย่างเซสชัน

ตัวนับจำนวนการดูเพจระหว่างเซสชัน ตัวอย่างผลงาน. อย่างไรก็ตาม หลังจากปิดเบราว์เซอร์ การนับถอยหลังจะเริ่มขึ้นใหม่

เคาน์เตอร์เข้าชมหน้าเดียวภายในช่วงเดียว

// ตัวอย่างง่ายๆ ของการใช้เซสชันโดยไม่มีคุกกี้
session_name ("ทดสอบ");
session_start ();
$ _SESSION ["นับ"] = @ $ _ SESSION ["นับ"] + 1;
?>

เคาน์เตอร์


ในเซสชันปัจจุบันของการทำงานกับเบราว์เซอร์ คุณได้เปิดหน้านี้
เวลา
ปิดเบราว์เซอร์ของคุณเพื่อรีเซ็ตตัวนับนี้
คลิกที่นี่เพื่อรีเฟรชหน้า!
ในการเปลี่ยนแต่ละครั้ง ตัวนับจะเพิ่มขึ้น 1)

ขอบคุณสำหรับความสนใจ! ขอให้โชคดีในความพยายามของคุณ!

เซสชั่นเป็นจริงง่ายมาก คุณเพียงแค่ต้องเข้าใจว่ามีไว้เพื่ออะไรและจัดการอย่างไร มาตอบคำถามแรกกันก่อน
คุณอาจรู้ว่าเว็บเซิร์ฟเวอร์ไม่รองรับ การเชื่อมต่อถาวรกับลูกค้า และแต่ละคำขอจะได้รับการประมวลผลเป็นคำขอใหม่ โดยไม่ต้องสื่อสารกับคำขอก่อนหน้านี้

นั่นคือ คุณไม่สามารถติดตามคำขอจากผู้เยี่ยมชมคนเดียวกัน หรือบันทึกตัวแปรสำหรับเขาระหว่างมุมมองต่างๆ แต่ละหน้า... เซสชันถูกคิดค้นขึ้นเพื่อแก้ปัญหาทั้งสองนี้
โดยสรุปแล้ว เซสชันเป็นกลไกที่ช่วยให้คุณระบุเบราว์เซอร์ได้โดยไม่ซ้ำกัน และสร้างไฟล์สำหรับเบราว์เซอร์นี้บนเซิร์ฟเวอร์ ซึ่งเก็บตัวแปรเซสชันไว้

ฉันจะไม่อธิบายรายละเอียดเกี่ยวกับความต้องการกลไกดังกล่าว กรณีเหล่านี้ เช่น ตะกร้าสินค้าในร้านค้าออนไลน์ การอนุญาต และไม่ใช่ปัญหาเล็กๆ น้อยๆ ทั้งหมด เช่น การปกป้องส่วนที่โต้ตอบของไซต์จากสแปม

โดยหลักการแล้ว มันค่อนข้างง่ายที่จะสร้างแอนะล็อกของเซสชันของคุณเอง ซึ่งใช้งานไม่ได้เท่ากับ PHP ในตัว แต่มีสาระสำคัญคล้ายกัน เกี่ยวกับคุกกี้และฐานข้อมูล

เมื่อขอสคริปต์ เราจะดูว่าคุกกี้มีชื่อเฉพาะหรือไม่ หากไม่มีคุกกี้ ให้ตั้งค่าและเขียนบรรทัดใหม่พร้อมข้อมูลผู้ใช้ลงในฐานข้อมูล หากมีคุกกี้ เราก็อ่านจากฐานข้อมูล ด้วยคำขออีกครั้ง เราจะลบบันทึกเก่าออกจากฐานข้อมูล และตอนนี้เรามีกลไกของเซสชันพร้อมแล้ว มันไม่ยากเลย แต่มีความแตกต่างบางประการที่ทำให้ควรใช้กลไกเซสชันในตัว

ก่อนอื่น คุณต้องระบุเบราว์เซอร์ก่อน การทำเช่นนี้คุณต้องให้เขา ตัวระบุที่ไม่ซ้ำและขอให้ส่งไปพร้อมกับคำขอทุกประการ ฉันรู้สึกละอายที่จะยอมรับ แต่เมื่อฉันเรียนรู้เกี่ยวกับเซสชันเป็นครั้งแรก ฉันคิดว่านี่เป็นกลไกพิเศษบางอย่าง ซึ่งเป็นวิธีใหม่ในการสื่อสารระหว่างเบราว์เซอร์และเซิร์ฟเวอร์ - "เซสชัน" ตัวระบุเซสชันจะถูกส่งผ่านด้วยวิธีพิเศษบางอย่าง แต่ความผิดหวังช่างโหดร้าย ...

เซสชันใช้วิธีการถ่ายโอนข้อมูลมาตรฐานและเป็นที่รู้จัก จริงๆแล้วไม่มีคนอื่น
ตัวระบุเป็นตัวแปรปกติ โดยค่าเริ่มต้น ชื่อของมันคือ PHPSESSID
หน้าที่ของ PHP คือส่งไปที่เบราว์เซอร์เพื่อส่งคืนพร้อมกับคำขอครั้งต่อไป จากส่วนคำถามที่พบบ่อยที่กล่าวถึงแล้ว เป็นที่ชัดเจนว่าตัวแปรสามารถส่งผ่านได้สองวิธีเท่านั้น: ในคุกกี้หรือในคำขอ POST / GET
PHP ใช้ทั้งสองตัวเลือก

การตั้งค่าสองอย่างใน php.ini รับผิดชอบสิ่งนี้:

session.use_cookies - ถ้าเท่ากับ 1 ดังนั้น PHP จะส่งตัวระบุไปยังคุกกี้ ถ้า 0 - แสดงว่าไม่ใช่
session.use_trans_sid ถ้าเท่ากับ 1 ดังนั้น PHP จะส่งผ่าน ต่อท้าย URL และแบบฟอร์ม ถ้า 0 - แสดงว่าไม่ใช่

คุณสามารถเปลี่ยนพารามิเตอร์เหล่านี้และพารามิเตอร์เซสชันอื่นๆ ได้ในลักษณะเดียวกับการตั้งค่า PHP อื่นๆ ในไฟล์ php.ini รวมถึงการใช้คำสั่ง ini_set () หรือในไฟล์การกำหนดค่าเว็บเซิร์ฟเวอร์

หากเปิดใช้งานเฉพาะครั้งแรก เมื่อเริ่มต้นเซสชัน (ที่การโทรแต่ละครั้ง session_start ()) คุกกี้ถูกตั้งค่าให้กับลูกค้า เบราว์เซอร์ส่งคืนคุกกี้นี้อย่างถูกต้องทุกครั้งที่มีการร้องขอ และ PHP มีตัวระบุเซสชัน ปัญหาเริ่มต้นถ้า คุกกี้เบราว์เซอร์ไม่กลับมา ในกรณีนี้ หากไม่มีคุกกี้พร้อมตัวระบุ PHP จะเริ่มเซสชันใหม่ตลอดเวลา และกลไกจะไม่ทำงาน

หากเปิดใช้งานเพียงตัวที่สอง จะไม่มีการตั้งค่าคุกกี้ และสิ่งที่เกิดขึ้นคือ โดยพื้นฐานแล้ว มันคุ้มค่าที่จะใช้กลไกเซสชันในตัว หลังจากที่สคริปต์ทำงาน และหน้าถูกสร้างขึ้นอย่างสมบูรณ์แล้ว PHP จะตรวจสอบทั้งหมดและผนวก ID เซสชันต่อท้ายลิงก์แต่ละลิงก์และแต่ละแบบฟอร์ม ดูเหมือนว่านี้:

ดัชนี

กลายเป็น

ดัชนี

และเพิ่มช่องที่ซ่อนอยู่ในแบบฟอร์ม

ในทางทฤษฎี ในเซสชันโฮมเมดของเรากับคุณเกี่ยวกับคุกกี้และฐาน คุณสามารถกำหนดการโอน id ไปยังลิงก์ทั้งหมดได้ด้วยตนเอง - จากนั้นเซสชันของเราจะทำงานโดยไม่คำนึงถึงคุกกี้ แต่คุณเห็นไหม - ดีกว่าเมื่อมีคนอื่นทำงานนี้ ;-)

ทั้งสองตัวเลือกถูกเปิดใช้งานโดยค่าเริ่มต้นใน PHP เวอร์ชันล่าสุด PHP จัดการกับสิ่งนี้อย่างไร คุกอยู่เสมอแสดง และลิงก์จะเติมข้อความอัตโนมัติก็ต่อเมื่อ PHP ไม่พบคุกกี้ที่มี ID เซสชัน เมื่อผู้ใช้เข้าชมไซต์เป็นครั้งแรกในระหว่างเซสชันนี้ คุกกี้จะถูกวางบนเขาและเพิ่มลิงก์ ในคำขอครั้งต่อไป หากรองรับคุกกี้ PHP จะเห็นคุกกี้และหยุดทำลิงก์ให้เสร็จ หากคุกกี้ไม่ทำงาน PHP ยังคงเพิ่ม id ไปยังลิงก์อย่างถูกต้องและเซสชันจะไม่สูญหาย
ผู้ใช้ที่มีคุกกี้จะเห็นลิงก์ยาวพร้อม ID เพียงครั้งเดียว

ด้วยการโอนตัวระบุเสร็จสิ้น ตอนนี้ยังคงผูกไฟล์ที่มีข้อมูลทางฝั่งเซิร์ฟเวอร์ไว้ PHP จะทำสิ่งนี้ให้เรา แค่เขียนว่า:

session_start ();
$ _SESSION ["test"] = "สวัสดีชาวโลก!" ;

และ PHP จะเขียนตัวแปรทดสอบไปยังไฟล์ที่เกี่ยวข้องกับเซสชันนี้

มีจุดสำคัญมากที่นี่

Array $ _SESSION- พิเศษ.
อันที่จริงเป็นตัวแปรที่เราต้องการให้พร้อมใช้งานในสคริปต์ต่างๆ
ในการวางตัวแปรในเซสชัน เพียงแค่กำหนดให้กับองค์ประกอบของอาร์เรย์ $ _SESSION
เพื่อให้ได้ค่ามันก็เพียงพอแล้วที่จะอ้างถึงองค์ประกอบเดียวกัน ตัวอย่างจะอยู่ด้านล่าง

การรวบรวมขยะ - การลบที่ล้าสมัย ไฟล์ PHPทำเองด้วย เช่นเดียวกับการเข้ารหัสข้อมูลและสิ่งอื่น ๆ ที่จำเป็น จากการดูแลนี้ การทำงานกับเซสชันจึงเป็นเรื่องง่ายมาก
อันที่จริงแล้ว เรามาถึงตัวอย่างการทำงานของเซสชัน
ตัวอย่างมีขนาดเล็กมาก:

session_start ();

เสียงก้อง "คุณได้อัปเดตหน้านี้"... $ _SESSION ["ตัวนับ"] ++ " ครั้งหนึ่ง. " ;
เสียงสะท้อน "
อัปเดต ";
?>

เราตรวจสอบว่าเรามีตัวแปรตัวนับในเซสชันหรือไม่ ถ้าไม่มี ให้สร้างด้วยค่า 0 แล้วส่งออกค่าของตัวแปรนั้นและเพิ่มขึ้นหนึ่งค่า ค่าที่เพิ่มขึ้นจะถูกเขียนไปยังเซสชัน และครั้งต่อไปที่มีการเรียกสคริปต์ ตัวแปรจะมีค่าเป็น 1 และอื่นๆ ทุกอย่างง่ายมาก

เพื่อให้สามารถเข้าถึงตัวแปรเซสชันบนหน้าใด ๆ ของไซต์ คุณต้องเขียนบรรทัดเดียวเท่านั้น (!) ที่จุดเริ่มต้นของแต่ละไฟล์ซึ่งเราต้องการเซสชัน:

session_start ();

session_start ();
ถ้า ($ _SESSION ["ได้รับอนุญาต"]<> 1 ) {
ส่วนหัว ("ตำแหน่ง: /auth.php");
ทางออก;
}

การลบตัวแปรออกจากเซสชัน หากคุณมี register_globals = off ก็เขียน

ยกเลิกการตั้งค่า ($ _ SESSION ["var"]);

ถ้าไม่เช่นนั้น ใกล้เคียงด้วยคุณต้องเขียน:

session_unregister ("var");

สิ่งสำคัญคือต้องเข้าใจว่าควรใช้เซสชันใดและไม่ควรใช้เซสชันใด

อันดับแรก จำไว้ว่าเซสชั่นสามารถใช้ได้เมื่อผู้ใช้ต้องการเท่านั้น ไม่ให้ขัดขวางเขา ท้ายที่สุด เขาสามารถกำจัดตัวระบุเมื่อใดก็ได้!
ตัวอย่างเช่น เมื่อตรวจสอบว่าบุคคลกรอกแบบฟอร์มและไม่ใช่สคริปต์ ผู้ใช้เองก็สนใจในเซสชันที่ทำงานอยู่ มิฉะนั้น เขาจะไม่สามารถส่งแบบฟอร์มได้! แต่สำหรับการจำกัดจำนวนคำขอสคริปต์ เซสชันไม่เหมาะสมอีกต่อไป - สคริปต์ที่เป็นอันตรายจะไม่ส่งคืนตัวระบุ

ประการที่สอง. สิ่งสำคัญคือต้องเข้าใจอย่างชัดเจนว่าเซสชันคือเซสชันของการทำงานกับไซต์ตามที่บุคคลเข้าใจ มาทำงานปิดเบราว์เซอร์ - เซสชันสิ้นสุดลง เหมือนตอนดูหนัง หากคุณต้องการดูอีก - ซื้อตั๋วใหม่ เริ่มเซสชันใหม่ นอกจากนี้ยังมีคำอธิบายทางเทคนิคสำหรับเรื่องนี้ รับประกันได้ว่ากลไกเซสชันจะทำงานจนกว่าเบราว์เซอร์จะปิดเท่านั้น ท้ายที่สุดแล้ว คุกกี้อาจไม่ทำงานสำหรับลูกค้า และแน่นอนว่าในกรณีนี้ ลิงก์ทั้งหมดที่เสริมด้วยตัวระบุจะหายไปเมื่อปิด

อย่างไรก็ตาม เซสชันอาจหายไปโดยไม่ต้องปิดเบราว์เซอร์ เนื่องจากข้อจำกัดที่กล่าวถึงในบทความนี้ กลไกจัดการเซสชันไม่สามารถตรวจพบเมื่อผู้ใช้ปิดเบราว์เซอร์ สำหรับสิ่งนี้ ระยะหมดเวลาถูกใช้ - เวลาที่กำหนดไว้ หลังจากนั้นเราถือว่าผู้ใช้ออกจากไซต์ไปแล้ว โดยค่าเริ่มต้น พารามิเตอร์นี้คือ 24 นาที

หากคุณต้องการบันทึกข้อมูลผู้ใช้เป็นเวลานาน ให้ใช้คุกกี้และฐานข้อมูลบนเซิร์ฟเวอร์หากจำเป็น โดยเฉพาะอย่างยิ่ง นี่คือวิธีการทำงานของระบบการอนุญาตที่เป็นที่นิยมทั้งหมด:

เมื่อระบุผู้ใช้แล้ว เซสชันจะเริ่มต้นขึ้นและสัญญาณการอนุญาตจะถูกส่งไปในนั้น
- หากจำเป็นต้อง "จำ" ผู้ใช้ คุกกี้จะถูกตั้งค่าเป็นผู้ใช้ซึ่งระบุตัวเขา
- ในครั้งต่อไปที่ผู้ใช้เข้าสู่ไซต์ เพื่อที่จะเข้าสู่ระบบ เขาต้องป้อนรหัสผ่าน มิฉะนั้นระบบจะรับรู้โดยคุกกี้ที่ตั้งไว้ก่อนหน้านี้ และเซสชันจะเริ่มต้นขึ้น เซสชันใหม่ แทนที่จะทำต่อในเซสชันเก่า

ประการที่สาม มันไม่คุ้มที่จะเริ่มต้นเซสชันตามอำเภอใจสำหรับทุกคนที่เข้าสู่ไซต์ สิ่งนี้จะสร้างภาระที่ไม่จำเป็นอย่างสมบูรณ์ อย่าใช้เซสชั่นสำหรับมโนสาเร่ - ตัวอย่างเช่นในเคาน์เตอร์ เซสชั่นการโทร spilogue แน่นอนนับตามสถิติการโทรและไม่ใช้กลไกเซสชันที่คล้ายกับ PHP

นอกจากนี้ ลองใช้เครื่องมือค้นหาที่จัดทำดัชนีไซต์ของคุณ หากโรบ็อตค้นหาไม่รองรับคุกกี้ ตามค่าเริ่มต้นแล้ว PHPSESSID จะส่ง PHPSESSID ไปยังลิงก์ ซึ่งอาจไม่เป็นที่พอใจสำหรับเสิร์ชเอ็นจิ้น ซึ่งตามข่าวลือ ไม่ชอบลิงก์ไดนามิกอยู่แล้ว แต่ที่นี่ โดยทั่วไป กับการโทรแต่ละครั้ง - ที่อยู่ใหม่!

หากเซสชันใช้เพื่อจำกัดการเข้าถึงส่วนปิดของไซต์ ทุกอย่างเป็นเพียงเครื่องมือค้นหาและไม่ควรจัดทำดัชนี หากคุณต้องแสดงหน้าเดียวกันแก่ผู้ใช้ทั้งที่ได้รับอนุญาตและไม่ได้รับอนุญาต เคล็ดลับดังกล่าวจะช่วยได้ - เพื่อเริ่มเซสชันเฉพาะกับผู้ที่ป้อนรหัสผ่านหรือผู้ที่เริ่มเซสชันแล้ว

เมื่อต้องการทำเช่นนี้ ที่จุดเริ่มต้นของแต่ละหน้า แทนที่จะเป็นเพียง session_start ()พวกเราเขียน:

if (isset ($ _ REQUEST [session_name ()])) session_start ();

ดังนั้นเราจึงเริ่มเซสชันเฉพาะผู้ที่ส่งตัวระบุเท่านั้น
ดังนั้นจึงจำเป็นต้องส่งให้ผู้ใช้เป็นครั้งแรก - ในขณะที่ได้รับอนุญาต

ถ้าชื่อและโรงจอดรถถูกต้อง - เขียน session_start () !

ข้อผิดพลาดที่พบบ่อยที่สุดที่ PHP ให้ไว้เมื่อพยายามทำงานกับเซสชันคือ:
ทั้งสอง,

คำเตือน: ไม่สามารถส่งคุกกี้ของเซสชัน - ส่งส่วนหัวแล้ว
คำเตือน: ไม่สามารถส่งตัวจำกัดแคชเซสชัน - ส่งส่วนหัวแล้ว

เกิดจากสาเหตุเดียวกัน การแก้ปัญหาได้อธิบายไว้ในข้อเท็จจริงนี้

คำเตือน: เปิด (/ tmp \ sess_SID, O_RDWR) ล้มเหลว: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว (2) ใน full_script_path ในหมายเลขบรรทัด

ก่อนหน้านี้เธอดูเหมือน

คำเตือน: ไม่สามารถเขียนข้อมูลเซสชัน (ไฟล์) โปรดตรวจสอบว่าการตั้งค่าปัจจุบันของ session.save_path ถูกต้อง (/ tmp) ,

หากแปลจากภาษาอังกฤษ จะอธิบายปัญหาโดยละเอียด: ไม่มีเส้นทางที่ระบุใน php.ini ไปยังไดเร็กทอรีที่เขียนไฟล์เซสชัน ข้อผิดพลาดนี้เป็นวิธีที่ง่ายที่สุดในการแก้ไข เพียงเขียนไดเร็กทอรีที่มีอยู่และสามารถเขียนได้ เช่น

session.save_path = c: \ windows \ temp

และอย่าลืมรีสตาร์ท Apache หลังจากนั้น

ปรากฏว่า สติปัญญาของมนุษย์ไม่มีขีดจำกัด ดังนั้นฉันจึงต้องอธิบาย:
ข้อความแสดงข้อผิดพลาดที่สาม (ไม่พบไดเร็กทอรี) จะ UNAVAILABLE นำไปสู่สองข้อความแรก เนื่องจากข้อความแสดงข้อผิดพลาดจะส่งออกไปยังเบราว์เซอร์ และคุณไม่สามารถใช้ส่วนหัวหลังจากนั้นได้ ดังนั้นอย่ารีบเร่งที่จะหาข้อสรุปก่อนเวลาอันควร แต่ก่อนอื่นให้เขียนเส้นทางที่ถูกต้อง!

ปัญหาที่พบบ่อยที่สุดรองลงมาเมื่อต้องรับมือกับเซสชันคือปัญหาใหญ่ของ register_globals อย่าให้ตัวแปรสคริปต์ชื่อเดียวกับดัชนีของอาร์เรย์ $ _SESSION!

เมื่อ register_globals = on ค่าต่างๆ จะเขียนทับกันและคุณจะสับสน

หากไม่ได้ผล แต่ไม่มีแสดงข้อความใด ๆ ให้เพิ่มสองบรรทัดที่จุดเริ่มต้นของสคริปต์ที่รับผิดชอบในการแสดงข้อผิดพลาดทั้งหมดบนหน้าจอ - ค่อนข้างเป็นไปได้ว่ามีข้อผิดพลาด แต่คุณไม่เห็น พวกเขา.

ini_set ("display_errors", 1);
error_reporting (E_ALL);

หรือเห็นข้อผิดพลาดใน error_log โดยทั่วไป หัวข้อของการแสดงข้อความแสดงข้อผิดพลาดอยู่นอกเหนือขอบเขตของบทความนี้ ดังนั้น อย่างน้อยต้องแน่ใจว่าคุณสามารถมองเห็นข้อความเหล่านั้นได้ คุณสามารถอ่านรายละเอียดเพิ่มเติมเล็กน้อยเกี่ยวกับการแก้ไขปัญหาในส่วนนี้

หากคุณแน่ใจว่าไม่มีข้อผิดพลาด แต่ตัวอย่างที่ให้มาใช้งานไม่ได้ เป็นไปได้ว่า PHP ไม่ได้เปิดใช้งานการถ่ายโอน id ผ่าน url และคุกกี้ด้วยเหตุผลบางอย่างไม่ทำงาน.
ดูสิ่งที่คุณมีกับคุกกี้

โดยทั่วไป หากเซสชันของคุณ "ไม่ทำงาน" ก่อนอื่นให้ลองโอนตัวระบุเซสชันด้วยตนเอง นั่นคือสร้างลิงก์และกำหนดตัวระบุให้กับเซสชันนั้น:

session_start ();
ถ้า (! isset ($ _ SESSION ["ตัวนับ"])) $ _SESSION ["ตัวนับ"] = 0;
เสียงก้อง "คุณได้อัปเดตหน้านี้"... $ _SESSION ["ตัวนับ"] ++ " ครั้งหนึ่ง.

อัปเดต ";
?>

เมื่อทำเช่นนี้ ตรวจสอบให้แน่ใจว่าไม่ได้เปิดใช้งานคำสั่ง session.use_only_cookies ซึ่งจะป้องกันไม่ให้ PHP ยอมรับ ID เซสชันหากส่งผ่าน URL

หากตัวอย่างนี้ใช้ไม่ได้ผล แสดงว่าปัญหาอยู่ใน banal ความผิดพลาด(ครึ่งหนึ่งของ "ปัญหา" ของเซสชันมาจากชื่อตัวแปรที่สะกดผิด) หรือใน PHP เวอร์ชันเก่าเกินไป: รองรับเซสชันปรากฏในเวอร์ชัน 4.0 และอาร์เรย์ $ _SESSION- ใน 4.1 (ก่อนหน้านี้ใช้ $ HTTP_SESSION_VARS).

หากใช้งานได้ แสดงว่าปัญหาอยู่ในคุกกี้ ติดตาม - คุกกี้ประเภทใดที่เซิร์ฟเวอร์ใส่ในเบราว์เซอร์ ไม่ว่าเบราว์เซอร์จะส่งคืนหรือไม่ การค้นหามีประโยชน์มากในขณะที่ดูการแลกเปลี่ยนส่วนหัว HTTP ระหว่างเบราว์เซอร์และเซิร์ฟเวอร์

การอธิบายวิธีการทำงานของคุกกี้นั้นอยู่นอกเหนือขอบเขตของสิ่งนี้และข้อความจำนวนมาก แต่อย่างน้อยตรวจสอบให้แน่ใจว่าเซิร์ฟเวอร์ส่งคุกกี้พร้อมตัวระบุและเบราว์เซอร์กลับมา และในขณะที่ตัวระบุตรงกัน =)
การตั้งค่าคุกกี้ควรมีลักษณะดังนี้

ชุดคุกกี้: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6;

ชุดคุกกี้: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6; เส้นทาง = /

(หากคุณกำลังขอสคริปต์ที่ไม่ได้มาจากไดเรกทอรีราก)
การตอบสนองของเซิร์ฟเวอร์ควรมีลักษณะดังนี้

คุกกี้: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6

คุกกี้: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6; ข = ข

หากเบราว์เซอร์ส่งคืนคุกกี้อื่นที่ไม่ใช่รหัสเซสชัน

หากตัวอย่างจากที่นี่ใช้งานได้ แต่รหัสของคุณใช้ไม่ได้ แสดงว่าปัญหาไม่ได้อยู่ที่เซสชัน แต่อยู่ในอัลกอริทึม ค้นหาตำแหน่งที่คุณสูญเสียตัวแปร โอนตัวอย่างจากที่นี่ทีละขั้นตอน ดีบักสคริปต์ของคุณ

ปัญหาอื่นอาจเกิดขึ้นได้หากคุณใช้การเปลี่ยนเส้นทางส่วนหัวหรือการนำทาง JavaScript
ความจริงก็คือ PHP ต่อท้ายตัวระบุเซสชันโดยอัตโนมัติเฉพาะกับลิงก์ของแบบฟอร์ม
แต่จะไม่ทำเช่นนี้กับส่วนหัว จาวาสคริปต์ เมตาแท็ก

ดังนั้น คุณต้องเพิ่มตัวระบุด้วยตนเอง เช่น:

ส่วนหัว ("ตำแหน่ง: /script.php?". session_name (). "=". session_id ());

นอกจากนี้ ปัญหาที่มาจากปัญหาที่พบได้น้อยมากและเข้าใจยากคือ การตั้งค่า session.save_handler มีค่าอื่นที่ไม่ใช่ไฟล์ หากไม่เป็นเช่นนั้นให้แก้ไข

  • นอกจากคุกกี้แล้ว กลไกเซสชันยังส่งส่วนหัวที่ห้ามการแคชหน้า (ตัวจำกัดแคชเดียวกัน) สำหรับ html สิ่งนี้ถูกต้องและจำเป็น แต่เมื่อคุณพยายามส่งไฟล์ที่มีสคริปต์ที่ตรวจสอบการอนุญาต Internet Explorer ปฏิเสธที่จะดาวน์โหลด เป็นเพราะชื่อนี้ เรียก
    session_cache_limiter ("ส่วนตัว");
    ต้องแก้ปัญหาก่อนเริ่มเซสชัน
  • ผิดปกติพอสมควร แต่ในอาร์เรย์ $ _SESSIONคุณไม่สามารถใช้ดัชนีตัวเลข - $ _SESSION [1], $ _SESSION ["10"]- เซสชันจะไม่ทำงาน
  • ไม่สามารถตั้งค่า session.use_trans_sid ด้วย . ระหว่าง 4.2 ถึง 5.0 ได้ ini_set ()... เริ่มต้นจาก 5.0 ก็เป็นไปได้อีกครั้ง
  • ก่อนหน้าเวอร์ชัน 4.3.3 คุกกี้ PHP ส่งคุกกี้เฉพาะเมื่อคำขอไม่มีตัวระบุเมื่อเริ่มต้นเซสชัน ตอนนี้คุกกี้จะถูกส่งไปทุกครั้งที่โทร session_start

    หากคุณมีคำถามเพิ่มเติมหรือบางอย่างไม่ชัดเจน - ยินดีต้อนรับสู่ .ของเรา

ตั้งแต่เริ่มต้น ทุกคนยอมรับ PHP อย่างไม่หยุดยั้ง แต่ทันทีที่พวกเขาเริ่มสร้างโครงการที่ใหญ่พอในภาษานี้ นักพัฒนาก็ประสบปัญหาใหม่ - ไม่มีแนวคิดของตัวแปรทั่วโลกใน PHP! นั่นคือ สคริปต์ถูกดำเนินการ ส่งหน้าที่สร้างขึ้นไปยังไคลเอนต์ และทรัพยากรทั้งหมดที่ใช้โดยสคริปต์นี้ถูกทำลาย เพื่อแสดงให้เห็น สมมติว่ามีสองหน้าในไซต์เดียวกันคือ index.php และ dothings.php แหล่งที่มาของหน้าเหล่านี้มีลักษณะดังนี้:

index.php dothings.php

หากคุณเรียกใช้สคริปต์ทั้งสองนี้ ในหน้าแรก เราจะเห็นข้อความจารึกว่า "ฉันถูกกำหนดให้กับ index.php" และหน้าที่สองจะว่างเปล่า

นักพัฒนาเว็บไซต์เริ่มใช้คุกกี้เพื่อเก็บตัวแปรทั่วโลกโดยไม่ลังเลใจในฝั่งไคลเอ็นต์ กระบวนการมีลักษณะดังนี้: ผู้ใช้มาที่หน้าแรกของไซต์ ดำเนินการบางอย่าง และข้อมูลทั้งหมดที่เกี่ยวข้องกับผู้ใช้รายนี้ ซึ่งอาจจำเป็นในหน้าอื่นของไซต์ จะถูกเก็บไว้ในเบราว์เซอร์ของเขาในแบบฟอร์ม ของคุกกี้ วิธีนี้มีข้อเสียค่อนข้างมาก เนื่องจากนักพัฒนาหลายคนหันหลังให้ PHP ในคราวเดียว ตัวอย่างเช่น เราต้องอนุญาตให้ผู้ใช้อนุญาตให้เขาเข้าถึงส่วนที่ถูกจำกัด (หรือเฉพาะของเขาเอง) ของไซต์ คุณจะต้องส่งคุกกี้ให้กับผู้ใช้ ซึ่งจะทำหน้าที่เป็นตัวระบุภายหลังบนไซต์ วิธีการนี้จะยุ่งยากและไม่สะดวกทันทีที่ไซต์เริ่มรวบรวมข้อมูลเพิ่มเติมเกี่ยวกับพฤติกรรมของผู้ใช้ เนื่องจากข้อมูลทั้งหมดที่ส่งไปยังผู้ใช้ควรได้รับการเข้ารหัสเพื่อไม่ให้ปลอมแปลงได้ เมื่อเร็วๆ นี้ การปลอมแปลงคุกกี้ทำให้สามารถ "ซ้อน" แชทได้มากกว่าหนึ่งแชท และบางครั้งอาจเข้าถึงอีเมลของคนอื่นได้ นอกจากนี้ยังมีคนแปลกหน้าในโลกที่เบราว์เซอร์ไม่รองรับคุกกี้

ฉันจะไม่พูดถึงปัญหาทางเทคโนโลยีของโครงสร้างของกลไกเซสชัน แต่จะอธิบายเฉพาะวิธีการทำงานอย่างถูกต้องกับเซสชันใน PHP เท่านั้น

วิธีการทำงานกับเซสชัน?

หากคุณทดสอบตัวอย่างจากบทความ (หรือสคริปต์ของคุณ) บนโฮสติ้งเชิงพาณิชย์ใด ๆ ไม่ควรมีปัญหากับการทำงานกับเซสชัน หากคุณตั้งค่าเซิร์ฟเวอร์ของคุณเอง (ไม่ว่าจะเป็นเซิร์ฟเวอร์จริงหรืออีมูเลเตอร์) ข้อผิดพลาดเกี่ยวกับเนื้อหาต่อไปนี้อาจปรากฏขึ้น:

"คำเตือน: เปิด (/ var / state / php / sess_6f71d1dbb52fa88481e752af7f384db0, O_RDWR) ล้มเหลว: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว (2)"

หมายความว่า PHP ของคุณได้รับการกำหนดค่าไม่ถูกต้อง คุณสามารถแก้ปัญหานี้ได้โดยการเขียนเส้นทางที่ถูกต้อง (ไปยังไดเร็กทอรีที่มีอยู่) เพื่อบันทึกเซสชันในไฟล์ php.ini และรีสตาร์ทเซิร์ฟเวอร์

สคริปต์ใด ๆ ที่จะใช้ตัวแปร (ข้อมูล) จากเซสชันควรมีบรรทัดต่อไปนี้:

Session_start ();

คำสั่งนี้บอกเซิร์ฟเวอร์ว่าหน้าที่กำหนดต้องการตัวแปรทั้งหมดที่เกี่ยวข้องกับผู้ใช้ที่กำหนด (เบราว์เซอร์) เซิร์ฟเวอร์ใช้ตัวแปรเหล่านี้จากไฟล์และทำให้พร้อมใช้งาน เป็นสิ่งสำคัญมากที่จะต้องเปิดเซสชันก่อนที่จะส่งข้อมูลใดๆ ไปยังผู้ใช้ ในทางปฏิบัติ แนะนำให้เรียกใช้ฟังก์ชัน session_start () ที่จุดเริ่มต้นของหน้า เช่น

Session_start (); ?> ... ในการตั้งค่าไดเร็กทอรีที่จะบันทึกไฟล์เซสชั่น ให้ใช้ฟังก์ชัน session_save_path () : session_save_path ($ _ SERVER ["DOCUMENT_ROOT"]. "/ Session"); session_start ();

เมื่อเริ่มเซสชันแล้ว คุณสามารถตั้งค่าตัวแปรส่วนกลางได้ เมื่อกำหนดค่าให้กับฟิลด์ใดๆ ในอาร์เรย์ $ _SESSION ตัวแปรที่มีชื่อเดียวกันจะถูกลงทะเบียนโดยอัตโนมัติเป็นตัวแปรเซสชัน อาร์เรย์นี้มีอยู่ในทุกหน้าที่ใช้เซสชัน ตัวอย่างเช่น มาวิเคราะห์โปรแกรมกัน:

index.php ตกลง. โหลดเซสชั่นแล้ว! มาดูกันดีกว่าว่ามีอะไรบ้าง: dothings.php

เมื่อไฟล์เหล่านี้ถูกรันตามลำดับ สคริปต์ "index.php" ตัวแรกจะให้ผลลัพธ์ดังต่อไปนี้:

ตกลง. โหลดเซสชั่นแล้ว! มาดูกันดีกว่าว่ามีอะไรบ้าง:

และ "dothings.php" ตัวที่สองคือ:

ฉันถูกถามที่ index.php

ตัวแปร $ a มีอยู่ในทุกหน้าของไซต์นี้ที่เริ่มเซสชัน

ฟังก์ชันและเทคนิคที่เป็นประโยชน์อื่นๆ สำหรับการทำงานกับเซสชัน:

  • ยกเลิกการตั้งค่า ($ _ SESSION ["a"])- เซสชัน "ลืม" ค่าของตัวแปรที่กำหนดโดยเซสชัน
  • session_destroy ()- เซสชันถูกทำลาย (เช่น หากผู้ใช้ออกจากระบบโดยกดปุ่ม "ออก")
  • session_set_cookie_params (อายุการใช้งาน int [, เส้นทางสตริง [, โดเมนสตริง]])- การใช้ฟังก์ชันนี้ คุณสามารถกำหนดระยะเวลาที่จะ "ใช้งาน" เซสชั่นได้โดยการตั้งค่า unix_timestamp ซึ่งจะกำหนดเวลาที่เซสชั่น "ตาย" โดยค่าเริ่มต้น เซสชันจะ "อยู่" จนกว่าไคลเอ็นต์จะปิดหน้าต่างเบราว์เซอร์
  • session_write_close ()- บันทึกตัวแปรเซสชันและปิด นี่เป็นสิ่งจำเป็นในการเปิดไซต์ในหน้าต่างใหม่ หากหน้าเว็บดำเนินการเป็นเวลานานและได้บล็อกไฟล์เซสชันสำหรับเบราว์เซอร์ของคุณ

ตัวอย่างของ

ทีนี้มาดูการใช้งานจริงของกลไกเซสชันกัน เราจะมาดูตัวอย่างง่ายๆ แต่มีประโยชน์สองสามตัวอย่าง

การให้สิทธิ์ผู้ใช้

คำถามเกี่ยวกับการอนุญาตผู้ใช้โดยใช้เซสชัน PHP จะถูกถามอย่างต่อเนื่องในการประชุมการเขียนโปรแกรมเว็บ กลไกการอนุญาตผู้ใช้ในระบบโดยใช้เซสชันนั้นค่อนข้างดีจากมุมมองด้านความปลอดภัย (ดูหัวข้อ)

ตัวอย่างของเราจะประกอบด้วยสามไฟล์: index.php, authorize.php และ secretplace.php ไฟล์ index.php มีแบบฟอร์มที่ผู้ใช้จะใส่ชื่อผู้ใช้และรหัสผ่าน แบบฟอร์มนี้จะส่งข้อมูลไปยังไฟล์ authorize.php ซึ่งในกรณีที่อนุญาตสำเร็จ จะอนุญาตให้ผู้ใช้เข้าถึงไฟล์ secretplace.php และแสดงข้อความแสดงข้อผิดพลาด

ตัวอย่าง: index.php ใส่รหัสผ่านของคุณ

เข้าสู่ระบบ:
รหัสผ่าน:
Authorize.php หน้า ... ส่วนหัว ("ตำแหน่ง: secretplace.php"); ทางออก; )) // หากมีสิ่งผิดปกติเกิดขึ้น ผู้ใช้จะได้รับ // ​​ข้อความแสดงข้อผิดพลาด ?> คุณป้อนรหัสผ่านไม่ถูกต้อง! secretplace.php เฮ้,,คุณอยู่ในเพจลับ!!! :)

ความปลอดภัย

ดังนั้น เราสามารถโอนตัวระบุจากหน้าหนึ่ง (สคริปต์ PHP) ไปยังหน้าอื่น (จนกว่าจะมีการโทรครั้งต่อไปจากไซต์ของเรา) ซึ่งหมายความว่าเราสามารถแยกแยะผู้เยี่ยมชมไซต์ทั้งหมดได้ เนื่องจากตัวระบุเซสชันเป็นตัวเลขที่มีขนาดใหญ่มาก (128 บิต) จึงไม่มีโอกาสเกิดขึ้นจริง ดังนั้นผู้โจมตีจึงเหลือตัวเลือกต่อไปนี้:

  • มีโทรจันในคอมพิวเตอร์ของผู้ใช้ที่ขโมยหมายเลขเซสชัน
  • ผู้โจมตีจับการรับส่งข้อมูลระหว่างคอมพิวเตอร์ของผู้ใช้กับเซิร์ฟเวอร์ แน่นอนว่ามีโปรโตคอล SSL ที่ปลอดภัย (เข้ารหัส) แต่ไม่ใช่ทุกคนที่ใช้มัน
  • เพื่อนบ้านเข้ามาที่คอมพิวเตอร์ของผู้ใช้ของเราและขโมยหมายเลขเซสชัน

สถานการณ์ดังกล่าวโดยพิจารณาจากข้อเท็จจริงที่ว่ามีคนขโมยบางสิ่งบางอย่างจากใครบางคนโดยทั่วไปไม่อยู่ในความสามารถของโปรแกรมเมอร์ สิ่งนี้ควรได้รับการดูแลโดยผู้ดูแลระบบและผู้ใช้เอง

อย่างไรก็ตาม PHP มักจะถูกหลอก มาดูจุดแฮ็กที่เป็นไปได้ในโปรแกรมการอนุญาตผู้ใช้:

  • ไฟล์ authorize.php - ความพยายามที่จะเดารหัสผ่านโดยใช้สคริปต์บุคคลที่สาม
  • ไฟล์ secretplace.php เป็นความพยายามในการหลอกลวงโปรแกรมโดยป้อนค่าของตัวแปร $ log_user ลงในแถบที่อยู่ของเบราว์เซอร์ เช่น
    "http://www.yoursite.ru/secretplace.php? log_user = แฮ็กเกอร์"

ดังนั้น ในโปรแกรมของเรา "หลุม" สองช่องจึงมองเห็นได้ชัดเจน หลุมหนึ่งมีขนาดเล็กและไม่สังเกตเห็นได้ชัดเจนเป็นพิเศษ แต่ช่องที่สองนั้นใหญ่มาก โดยที่แฮ็กเกอร์ส่วนใหญ่จะปีนขึ้นไปโดยไม่จำเป็น

วิธีการ "แพทช์" หลุมที่ 1?

เราจะไม่เขียนโค้ดจำนวนมากเพื่อบล็อกที่อยู่ IP ฯลฯ แต่เพียงแค่ตรวจสอบว่าคำขอมาจากที่ใด หรือมากกว่าที่คำขอมาจากหน้า หากเป็นหน้าใด ๆ จากไซต์ของเรา ทุกอย่างก็เรียบร้อยดี แต่ ในกรณีอื่นๆ ทั้งหมด เราจะไม่ปล่อยให้มันเข้ามา มาแก้ไขไฟล์ authorize.php กันเถอะ:

Authorize.php V2 หน้า ... ส่วนหัว ("ตำแหน่ง: secretplace.php"); ทางออก; )))?> คุณป้อนรหัสผ่านไม่ถูกต้อง!
วิธีกำจัด "หลุม" หมายเลข 2?

สมมติว่าคุณมีเว็บไซต์ที่มนุษย์ทุกคนสามารถลงทะเบียนเพื่อโพสต์ในฟอรัมได้ โดยปกติ ในฟอรัมผู้ใช้บางคน (ผู้ดูแลระบบ ผู้ตรวจสอบ) จะมีโอกาสมากกว่าคนอื่นๆ เช่น พวกเขาสามารถลบข้อความจากผู้ใช้รายอื่นได้ คุณเก็บระดับการเข้าถึงของผู้ใช้ในเซสชันในตัวแปร $ user_status โดยที่ $ user_status = 10 สอดคล้องกับ การเข้าถึงแบบเต็มให้กับระบบ ผู้โจมตีที่มายังไซต์เพียงแค่ต้องลงทะเบียนตามปกติ แล้วเพิ่มในแถบที่อยู่ของเบราว์เซอร์ ? user_status = 10... ดังนั้นคุณจึงมีผู้ดูแลระบบใหม่ในฟอรัมของคุณ!

โดยพื้นฐานแล้ว ตัวแปรสคริปต์ใดๆ สามารถตั้งค่าได้ผ่าน แถบที่อยู่โดยเพียงแค่เพิ่มเครื่องหมายคำถามและชื่อของตัวแปรด้วยค่าหลังที่อยู่แบบเต็มของสคริปต์ มาแก้ไขรหัสของเราเพื่อหลีกเลี่ยงสิ่งนี้:

secretplace.php V2 ยกเลิกการตั้งค่าตัวแปร ($ _ SESSION ["logged_user"]); // เปิดเซสชัน session_start (); / * คุณไม่สามารถไปที่หน้านี้ได้ ... หากชื่อผู้ใช้ไม่ได้ลงทะเบียน เราจะเปลี่ยนเส้นทางไปที่หน้า index.php เพื่อเข้าสู่ระบบและรหัสผ่าน ... ในความเป็นจริงคุณสามารถทำอะไรได้มากมาย ตัวอย่างเช่น จำ IP ของผู้ใช้ และหลังจากพยายามเข้าถึงไฟล์เป็นครั้งที่สาม ให้บล็อกมัน * / if (! isset ($ _ SESSION ["logged_user"])) (ส่วนหัว ("ตำแหน่ง: index.php"); exit;)?> เฮ้,คุณอยู่ในเพจลับ! ผลลัพธ์

กลไกเซสชั่นเป็นคุณสมบัติที่ยอดเยี่ยมมาก ภาษา PHP... เซสชันนั้นเรียบง่าย ยืดหยุ่นมากในการใช้งาน อนึ่ง มีโอกาสหนึ่งที่ไม่ค่อยมีการบันทึกไว้ เซสชัน PHP(มีตั้งแต่เวอร์ชัน 4.0.3) - ไม่เพียงแต่ตัวแปรเท่านั้น แต่ยังสามารถเก็บอ็อบเจ็กต์ในเซสชันได้อีกด้วย

ตัวอย่างของ

?>
// การแทรก SID ลงในลิงก์โดยอัตโนมัติ ini_set ("session.use_trans_sid", จริง); session_start (); ?> คลิกที่นี่!
คลิกที่นี่ !!

// ตัวอย่างการทำงานกับเซสชัน session_start (); // หากเพิ่งเข้าชมไซต์ ให้รีเซ็ตตัวนับ ถ้า (! isset ($ _ SESSION ["count"])) $ _SESSION ["count"] = 0; // เพิ่มตัวนับในเซสชั่น $ _SESSION ["นับ"] = $ _SESSION ["นับ"] + 1; ?>

เคาน์เตอร์

เวลา
ปิดเบราว์เซอร์ของคุณเพื่อรีเซ็ตตัวนับ
"target =" _blank "> เปิดหน้าต่างเบราว์เซอร์ลูก
// ตัวอย่างง่ายๆ ของการใช้เซสชันโดยไม่มีคุกกี้ session_name ("ทดสอบ"); session_start (); $ _SESSION ["นับ"] = @ $ _ SESSION ["นับ"] + 1; ?>

เคาน์เตอร์

ในเซสชันปัจจุบันของการทำงานกับเบราว์เซอร์ คุณได้เปิดหน้านี้เวลา
ปิดเบราว์เซอร์ของคุณเพื่อรีเซ็ตตัวนับนี้
?"> คลิกที่นี่เพื่อรีเฟรชหน้า!

เซสชันเป็นวิธีง่ายๆ ในการจัดเก็บข้อมูลสำหรับผู้ใช้แต่ละรายด้วยรหัสเซสชันที่ไม่ซ้ำกัน สามารถใช้เพื่อรักษาสถานะระหว่างคำขอของเพจ โดยปกติ ID เซสชันจะถูกส่งไปยังเบราว์เซอร์ผ่านคุกกี้เซสชันและใช้เพื่อดึงข้อมูลเซสชันที่มีอยู่ การไม่มี ID เซสชันหรือคุกกี้เซสชันบอกให้ PHP สร้างเซสชันใหม่และสร้าง ID เซสชันใหม่

เซสชันใช้เทคโนโลยีที่เรียบง่าย เมื่อสร้างเซสชันแล้ว PHP จะได้รับเซสชันที่มีอยู่โดยใช้ตัวระบุที่ส่งผ่าน (โดยปกติมาจากคุกกี้ของเซสชัน) หรือหากไม่มีสิ่งใดผ่าน เซสชันใหม่จะถูกสร้างขึ้น PHP จะเติม $ _SESSION superglobal ด้วยข้อมูลเซสชันหลังจากเริ่มเซสชัน เมื่อออกจาก PHP จะทำให้เนื้อหาของ $ _SESSION superglobal เป็นอนุกรมโดยอัตโนมัติ และส่งไปยังที่เก็บข้อมูลโดยใช้ตัวจัดการเซสชันเพื่อบันทึกเซสชัน

ตามค่าเริ่มต้น PHP จะใช้ตัวจัดการไฟล์ภายในเพื่อบันทึกเซสชัน ซึ่งตั้งค่าไว้ในตัวแปร INI ของ session.save_handler ตัวจัดการนี้บันทึกข้อมูลบนเซิร์ฟเวอร์ในไดเร็กทอรีที่ระบุในคำสั่งคอนฟิกูเรชัน session.save_path

สามารถเริ่มเซสชันได้ด้วยตนเองโดยใช้ฟังก์ชัน session_start ()... หากกำหนดคำสั่ง session.auto_start เป็น 1 เซสชันจะเริ่มต้นโดยอัตโนมัติเมื่อเริ่มต้นคำขอ

เซสชันมักจะสิ้นสุดลงเมื่อ PHP ดำเนินการสคริปต์เสร็จสิ้น แต่ก็สามารถยุติได้ด้วยตนเองโดยใช้ฟังก์ชัน session_write_close ().

คำเตือน

ความสนใจ

ความคิดเห็น:

เซสชันที่ใช้ไฟล์ (ค่าเริ่มต้นใน PHP) จะบล็อกไฟล์เซสชันทันทีที่เปิดเซสชันด้วยฟังก์ชัน session_start ()หรือทางอ้อมโดยระบุ session.auto_start หลังจากบล็อกแล้ว สคริปต์อื่นจะไม่สามารถเข้าถึงไฟล์เซสชันเดียวกันได้จนกว่าจะปิดหรือเมื่อสคริปต์สิ้นสุดหรือเมื่อมีการเรียกใช้ฟังก์ชัน session_write_close ().

นี่น่าจะเป็นปัญหาสำหรับไซต์ที่ใช้ AJAX เป็นจำนวนมากและสร้างคำขอพร้อมกันหลายรายการ วิธีที่ง่ายที่สุดในการแก้ปัญหานี้คือเรียกใช้ฟังก์ชัน session_write_close ()ทันทีที่มีการเปลี่ยนแปลงที่จำเป็นทั้งหมดในเซสชั่น ควรให้ใกล้กับจุดเริ่มต้นของสคริปต์ คุณยังสามารถใช้กลไกเซสชันอื่นที่สนับสนุนการทำงานพร้อมกันได้

ฉันไม่ทราบสาเหตุ แต่ลองทั้งหมด / google คำตอบ .. ฉันไม่พบอะไรเลย นี่คือสถานการณ์:

รหัสโฮสต์ท้องถิ่น

ผลลัพธ์:

ลำดับ session_id () ข้ามหน้าแอปและรีเฟรชหน้า $ _COOKIE ["PHPSESSID"] ตรงกับ session_id ()

เซิร์ฟเวอร์โดยตรง

Session_start (); เสียงสะท้อน session_id (); print_r ($ _ คุกกี้ ["PHPSESSID"]);

ผลลัพธ์:

session_id () เปลี่ยนแปลงในทุกคำขอ โหลดหน้าซ้ำ หรือไปที่หน้าอื่น $ _COOKIE ["PHPSESSID"] เป็น NULL / ว่างเปล่า ใช้รหัสเดียวกันที่ด้านบนของหน้า ไม่มีเนื้อหาอื่น ๆ

ปัญหานี้ทำให้ฉันปวดหัวจริงๆ การกำหนดค่าเซิร์ฟเวอร์หรือข้อผิดพลาดประเภทใดที่อาจทำให้เกิดสิ่งนี้ เหตุใดคุกกี้ PHPSESSID จึงว่างเปล่า ฉันเชื่อว่าเป็นเพราะ session_id () ที่เกี่ยวข้องถูกรีเซ็ตในทุกคำขอด้วย

ความช่วยเหลือใด ๆ ได้โปรด!

แก้ไข: ฉันสร้างไฟล์ทดสอบอย่างง่ายด้วย 3 บรรทัดบนเซิร์ฟเวอร์ระยะไกลในพื้นที่ของฉัน ไม่เกี่ยวข้องกับรหัสของฉัน $ _COOKIE ["PHPSESSID"] ยังคงว่างเปล่าและมี session_id () ใหม่เกิดขึ้นบนโฮสต์จริงในทุกการอัปเดต

error_reporting SET TO ALL ฉันได้รับสิ่งนี้จากโฮสต์สด:

ประกาศ: ดัชนีที่ไม่ได้กำหนด: PHPSESSID ใน /home/vivaplug/public_html/dev/wp-content/plugins/test.php ที่บรรทัด 5

ส่วนหัวของ Google Chrome

LOCALHOST

URL คำขอ: http: //localhost/wp-content/plugins/test.php วิธีการขอ: GET รหัสสถานะ: 200 ตกลง คำขอ Headersview source ยอมรับ: ข้อความ / html, แอปพลิเคชัน / xhtml + xml, แอปพลิเคชัน / xml; q = 0.9, รูปภาพ / webp, * / *; q = 0.8 การเข้ารหัสที่ยอมรับ: gzip, deflate, sdch Accept-Language: en-US, en; q = 0.8 Cache-Control: no-cache การเชื่อมต่อ: keep-alive Cookie: PHPSESSID = 68b7m4arpsacks4aetgmd3rs93 โฮสต์: localhost Pragma: ไม่มีแคช User-Agent: Mozilla / 5.0 (Windows NT 6.1) AppleWebKit / 537.36 (KHTML เช่น Gecko) Chrome / 30.0.1599.101 Safari / 537.36 Response Headersview source Cache-Control: no-store, no- cache, must-revalidate, post-check = 0, pre-check = 0 Connection: Keep-Alive Content-Type: text / html Date: อ. 05 พ.ย. 2556 07:10:51 GMT หมดอายุ: พฤหัสบดี 19 พ.ย. 1981 08 : 52: 00 GMT Keep-Alive: หมดเวลา = 5, สูงสุด = 100 Pragma: เซิร์ฟเวอร์ไม่มีแคช: Apache / 2.4.4 (Win32) PHP / 5.4.16 การเข้ารหัสการถ่ายโอน: ชิ้น X-Powered-By: PHP / 5.4 .16

ลบเซิร์ฟเวอร์

URL คำขอ: http: //vivaplugins.com/dev/wp-content/plugins/test.php วิธีการขอ: GET รหัสสถานะ: 200 ตกลง ขอส่วนหัวดูแหล่งที่มา ยอมรับ: ข้อความ / html, แอปพลิเคชัน / xhtml + xml, แอปพลิเคชัน / xml; q = 0.9, รูปภาพ / webp, * / *; q = 0.8 การเข้ารหัสที่ยอมรับ: gzip, deflate, sdch Accept-Language: en-US, en; q = 0.8 Cache-Control: max-age = 0 การเชื่อมต่อ: keep- มีชีวิตอยู่ โฮสต์: vivaplugins.com ตัวแทนผู้ใช้: Mozilla / 5.0 (Windows NT 6.1) AppleWebKit / 537.36 (KHTML เช่น Gecko) Chrome / 30.0.1599.101 Safari / 537.36 การตอบสนอง Headersview source อายุ: 0 การควบคุมแคช: ไม่มีการจัดเก็บ ไม่มี -cache, must-revalidate, post-check = 0, pre-check = 0 Content-Encoding: gzip Content-Type: text / html Date: Tue, 05 พฤศจิกายน 2013 07:07:49 GMT Pragma: no-cache Server: โฮสติ้งขั้นสูงโดย http://www.unixy.net/varnish Transfer-Encoding: chunked Vary: Accept-Encoding Via: 1.1 วานิช X-Cache: HIT X-Cache-Hits: 2 X-Cacheable: ใช่ X-Powered-By : PHP / 5.4.20 X-วานิช: 1984840969 1984839805