首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 登入/登出系統實作:Session 驗證、Cookie 自動登入與安全登出流程

     編輯:PHP 相關知識

資料庫準備

CREATE TABLE pm_user (
    u_id INT AUTO_INCREMENT PRIMARY KEY,
    u_user VARCHAR(50) NOT NULL UNIQUE,
    u_pwd  VARCHAR(255) NOT NULL,  -- 存 password_hash()
    u_name VARCHAR(50)
);

核心邏輯檔案

1. 登入頁 login.htm(靜態表單)

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>登入</title></head>
<body>
<form method="post" action="login.php">
    帳號:<input type="text" name="user" id="user" required><br>
    密碼:<input type="password" name="pwd" id="pwd" required><br>
    <button type="submit" name="button">提交</button>
</form>
</body></html>

2. 登入驗證 login.php

<?php
session_start();
// 現代寫法:使用 mysqli + 預處理 + password_hash
$mysqli = new mysqli('localhost', 'root', 'password', 'dbname');
if ($mysqli->connect_errno) die("DB連線失敗");

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $user = trim($_POST['user'] ?? '');
    $pwd  = $_POST['pwd'] ?? '';

    if ($user && $pwd) {
        $stmt = $mysqli->prepare("SELECT u_id, u_user, u_pwd FROM pm_user WHERE u_user = ?");
        $stmt->bind_param("s", $user);
        $stmt->execute();
        $result = $stmt->get_result();

        if ($row = $result->fetch_assoc()) {
            if (password_verify($pwd, $row['u_pwd'])) {
                // 登入成功,建立 session
                $_SESSION['user_id'] = $row['u_id'];
                $_SESSION['user']    = $row['u_user'];
                $_SESSION['name']    = $row['u_name'];

                // 記住我功能(可選)
                if (!empty($_POST['remember'])) {
                    $token = bin2hex(random_bytes(32));
                    setcookie('auth_token', $token, time() + 30*86400, '/', '', true, true);
                    // 這裡應將 token 存入資料庫關聯 user_id
                }

                header('Location: index.php');
                exit;
            }
        }
        $error = "帳號或密碼錯誤";
    } else {
        $error = "請輸入帳號密碼";
    }
}
?>
<!DOCTYPE html>
<html><body>
<?php if (!empty($error)) echo "<p style='color:red'>$error</p>"; ?>
<form method="post">
    帳號:<input type="text" name="user" required><br>
    密碼:<input type="password" name="pwd" required><br>
    <label><input type="checkbox" name="remember"> 記住我</label><br>
    <button type="submit">登入</button>
</form>
</body></html>

3. 頁面存取控制 auth.php(共用引入)

<?php
session_start();

function checkLogin() {
    // 1. Session 已存在
    if (isset($_SESSION['user_id'])) return true;

    // 2. 嘗試從 Cookie 恢復(記住我功能)
    if (isset($_COOKIE['auth_token'])) {
        $token = $_COOKIE['auth_token'];
        // 這裡查資料庫驗證 token 有效性並取得 user_id
        // 簡化示範:
        $mysqli = new mysqli('localhost', 'root', 'password', 'dbname');
        $stmt = $mysqli->prepare("SELECT u_id, u_user, u_name FROM pm_user WHERE auth_token = ?");
        $stmt->bind_param("s", $token);
        $stmt->execute();
        $row = $stmt->get_result()->fetch_assoc();
        if ($row) {
            $_SESSION['user_id'] = $row['u_id'];
            $_SESSION['user']    = $row['u_user'];
            $_SESSION['name']    = $row['u_name'];
            return true;
        }
    }
    return false;
}

// 未登入導向登入頁
if (!checkLogin()) {
    header('Location: login.htm');
    exit;
}
?>

4. 會員頁 index.php

<?php require 'auth.php'; ?>
<!DOCTYPE html>
<html><body>
<h2>歡迎,<?= htmlspecialchars($_SESSION['user']) ?></h2>
<p>User ID: <?= $_SESSION['user_id'] ?></p>
<a href="logout.php">登出</a>
</body></html>

5. 登出 logout.php

<?php
session_start();

// 清除記住我 Cookie
if (isset($_COOKIE['auth_token'])) {
    setcookie('auth_token', '', time() - 3600, '/', '', true, true);
    // 這裡也應清除資料庫中的 token
}

// 銷毀 Session
$_SESSION = [];
session_destroy();

header('Location: login.htm');
exit;
?>

安全性關鍵點總結

項目建議做法
密碼儲存password_hash($pwd, PASSWORD_DEFAULT) + password_verify()
SQL 注入防護全程使用預處理語句
Session 劫持防護session.cookie_httponly=1、session.cookie_secure=1 (HTTPS)、session.use_strict_mode=1
CSRF 防護表單加入 $_SESSION['csrf_token'] 驗證
暴力破解防護登入失敗計數 + 延遲/鎖定 + 驗證碼
記住我 Token隨機 32+ 位元組、資料庫存雜湊、設定過期時間、HTTPS Only

原始碼中已棄用功能提醒

  • mysql_* 函數:PHP 7.0 移除,必須改用 mysqli 或 PDO
  • session_register():PHP 5.4 移除,直接操作 $_SESSION
  • SHA() 資料庫函數:不可逆但非專為密碼設計,請用 password_hash()
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved