Kodokon kodokon.com

เซสชันและคุกกี้: การเข้าสู่ระบบและตะกร้าสินค้า

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

10 นาที · 3 คำถาม

เปิดบทเรียนนี้ใน Kodokon

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

PHP
<?php

declare(strict_types=1);

session_start();

$storedHash = password_hash('secret123', PASSWORD_DEFAULT);
$password = $_POST['password'] ?? '';

if (password_verify($password, $storedHash)) {
    session_regenerate_id(true);
    $_SESSION['user_id'] = 42;
    header('Location: /account.php');
    exit;
}

echo "Invalid credentials.";
login.php: ในความเป็นจริง แฮชมาจากฐานข้อมูลของคุณ

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

PHP
<?php

declare(strict_types=1);

session_start();

if (!isset($_SESSION['user_id'])) {
    header('Location: /login.php');
    exit;
}

$_SESSION['cart'] ??= [];

$productId = filter_input(
    INPUT_POST,
    'product_id',
    FILTER_VALIDATE_INT
);

if (is_int($productId)) {
    $qty = $_SESSION['cart'][$productId] ?? 0;
    $_SESSION['cart'][$productId] = $qty + 1;
}

$count = array_sum($_SESSION['cart']);
echo "Cart: " . $count . " item(s)";
cart.php: หน้าที่ถูกปกป้องและตะกร้าที่เก็บไว้ในเซสชัน

ส่วนคุกกี้นั้นอาศัยอยู่ บนอุปกรณ์ของผู้ใช้ และคงอยู่แม้ปิดเบราว์เซอร์ไปแล้ว เหมาะอย่างยิ่งสำหรับธีมหรือการตั้งค่าภาษา ตั้งแต่ PHP 7.3 เป็นต้นมา setcookie() รับอาร์เรย์ของตัวเลือกได้ ให้กำหนด secure (ผ่าน HTTPS เท่านั้น), httponly (มองไม่เห็นจาก JavaScript) และ samesite (จำกัดการส่งจากเว็บไซต์อื่น)

PHP
<?php

setcookie('theme', 'dark', [
    'expires' => time() + 60 * 60 * 24 * 30,
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);

$theme = $_COOKIE['theme'] ?? 'light';
echo "Active theme: " . $theme;
คุกกี้การตั้งค่าที่มีอายุสามสิบวัน พร้อมแฟล็กที่ถูกต้อง

การออกจากระบบต้องทำอย่างรอบคอบพอ ๆ กับการเข้าสู่ระบบ ล้าง $_SESSION ให้ว่าง ทำลายเซสชันฝั่งเซิร์ฟเวอร์ และทำให้คุกกี้ที่พาตัวระบุมาหมดอายุ

PHP
<?php

session_start();

$_SESSION = [];
session_destroy();

setcookie(session_name(), '', time() - 3600, '/');

header('Location: /login.php');
exit;
logout.php: การออกจากระบบอย่างสมบูรณ์ ไม่ทิ้งร่องรอยไว้

ทดสอบความรู้

ตรวจสอบว่าคุณจำประเด็นสำคัญของบทเรียนนี้ได้ครบถ้วน

  1. ข้อมูลของเซสชัน PHP ถูกเก็บไว้ที่ไหน?
    • ในคุกกี้บนอุปกรณ์ของผู้ใช้
    • บนเซิร์ฟเวอร์ ส่วนเบราว์เซอร์เก็บเพียงตัวระบุไว้ในคุกกี้
    • ใน URL ของแต่ละหน้า
    • ใน localStorage ของเบราว์เซอร์
  2. ทำไมต้องเรียก session_regenerate_id(true) ทันทีหลังจากเข้าสู่ระบบสำเร็จ?
    • เพื่อป้องกันการตรึงเซสชัน (session fixation) ตัวระบุที่ถูกรู้ก่อนการเข้าสู่ระบบจะใช้การไม่ได้
    • เพื่อขยายอายุของคุกกี้เซสชัน
    • เพื่อล้างข้อมูลตะกร้าเดิม
  3. ตัวเลือก httponly ของคุกกี้ทำหน้าที่อะไร?
    • มันเข้ารหัสเนื้อหาของคุกกี้
    • มันจำกัดคุกกี้ให้ใช้ได้เฉพาะการเชื่อมต่อที่ไม่ปลอดภัย
    • มันทำให้ JavaScript ของหน้าเว็บเข้าถึงคุกกี้ไม่ได้ ซึ่งจำกัดการขโมยผ่าน XSS