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

PHP 簡易後台用戶登入實作:SAE 平台、SaeMysql、JSON 回應與安全最佳實踐

     編輯:PHP 相關知識

PHP 簡易後台用戶登入實作:SAE 平台、SaeMysql、JSON 回應與安全最佳實踐

輕量級專案(如行動 App 後端、內部管理系統)常需快速建立登入 API。本文以新浪雲(SAE)平台為例,示範 SaeMysql 連線、參數接收、密碼驗證、JSON 統一回應格式,並補充通用 PHP(PDO/MySQLi)寫法與關鍵安全強化點。

一、SAE 平台專用實作(SaeMysql)

<?php
// login.php - SAE 版
header('Content-Type: application/json; charset=utf-8');

// 1. 統一回應格式
function jsonResponse(bool $success, string $message = '', array $data = [], int $code = 200) {
    http_response_code($code);
    echo json_encode(['success' => $success, 'message' => $message, 'data' => $data], JSON_UNESCAPED_UNICODE);
    exit;
}

// 2. 參數接收(支援 GET/POST/JSON)
$input = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $contentType = $_SERVER['CONTENT_TYPE'] ?? '';
    if (strpos($contentType, 'application/json') === 0) {
        $input = json_decode(file_get_contents('php://input'), true) ?? [];
    } else {
        $input = $_POST;
    }
} else {
    $input = $_GET;
}
$username = trim($input['username'] ?? '');
$password = $input['password'] ?? '';

if ($username === '' || $password === '') {
    jsonResponse(false, '帳號密碼不可為空', [], 400);
}

// 3. SAE 專用資料庫連線
try {
    $mysql = new SaeMysql(); // SAE 內建,無需 host/user/pass
    // 防注入:使用預處理(SaeMysql 支援 prepare/execute)
    $stmt = $mysql->prepare('SELECT id, username, password_hash, status FROM admin_users WHERE username = ?');
    $stmt->bind_param('s', $username);
    $stmt->execute();
    $result = $stmt->get_result();
    $user = $result->fetch_assoc();
    $stmt->close();
} catch (Exception $e) {
    error_log('DB Error: ' . $e->getMessage());
    jsonResponse(false, '系統錯誤,請稍後再試', [], 500);
}

// 4. 驗證
if (!$user) {
    jsonResponse(false, '帳號不存在', [], 401);
}
if ($user['status'] !== 1) {
    jsonResponse(false, '帳號已停用', [], 403);
}
// 密碼驗證:假設資料庫存 password_hash() 雜湊
if (!password_verify($password, $user['password_hash'])) {
    jsonResponse(false, '密碼錯誤', [], 401);
}

// 5. 登入成功:建立 Session/Token
session_start();
$_SESSION['admin_id'] = $user['id'];
$_SESSION['admin_user'] = $user['username'];
session_regenerate_id(true); // 防 Session Fixation

jsonResponse(true, '登入成功', [
    'user_id' => $user['id'],
    'username' => $user['username'],
    'token' => session_id(), // 簡易示範,實際建議 JWT
]);

二、通用 PHP(PDO/MySQLi)版本

<?php
// 通用 PDO 版本(適用所有環境)
$dsn = 'mysql:host=localhost;dbname=myapp;charset=utf8mb4';
$pdo = new PDO($dsn, 'db_user', 'db_pass', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false,
]);

$stmt = $pdo->prepare('SELECT id, username, password_hash, status FROM admin_users WHERE username = ?');
$stmt->execute([$username]);
$user = $stmt->fetch();
// 後續驗證邏輯相同

三、資料表結構與密碼雜湊

CREATE TABLE admin_users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL UNIQUE,
    password_hash VARCHAR(255) NOT NULL, -- 存 password_hash() 結果
    status TINYINT DEFAULT 1, -- 1=正常, 0=停用
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 建立測試帳號(密碼:admin123)
INSERT INTO admin_users (username, password_hash) VALUES 
('admin', '$2y$10$AbCdEfGhIjKlMnOpQrStUvWxYz1234567890AbCdEfGhIjKlMnOpQr'); -- password_hash('admin123', PASSWORD_DEFAULT)

四、安全最佳實踐清單

項目做法風險若不做
密碼儲存password_hash() + password_verify(),禁用 MD5/SHA1/明文資料庫洩露即全盤帳號失陷
SQL 注入全站預處理(PDO/SaeMysql prepare),拒絕字串拼接繞過登入、資料竊取/刪除
暴力破解失敗計數 + 延遲/鎖定 + 驗證碼 + IP 限流短時間嘗試大量密碼
Session 安全httponly、secure、regenerate_id、Redis 分散式儲存XSS 竊取 Session、Session Fixation
傳輸加密全站 HTTPS,session.cookie_secure=1中間人竊取帳密/Session
錯誤資訊生產環境不輸出 SQL/堆疊,統一代碼回應洩露資料庫結構、路徑
CORS明確 Access-Control-Allow-Origin,不可 *跨站請求偽造 (CSRF)

五、進階:JWT 無狀態 Token(替代 Session)

<?php
// 登入成功後簽發 JWT(需 firebase/php-jwt)
use Firebase\JWT\JWT;
$payload = [
    'iss' => 'myapp',
    'sub' => $user['id'],
    'iat' => time(),
    'exp' => time() + 3600, // 1 小時
    'username' => $user['username'],
];
$jwt = JWT::encode($payload, 'your_secret_key', 'HS256');
jsonResponse(true, '登入成功', ['token' => $jwt, 'expires_in' => 3600]);

// 後續 API 驗證中介軟體
function authMiddleware(): ?array {
    $auth = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
    if (preg_match('/Bearer\s+(.+)/', $auth, $m)) {
        try {
            return JWT::decode($m[1], 'your_secret_key', ['HS256']);
        } catch (Exception $e) { return null; }
    }
    return null;
}

總結: 簡易登入核心在於「參數接收 → 預處理查詢 → password_verify → Session/JWT 簽發 → JSON 回應」。SAE 環境用 SaeMysql,通用環境用 PDO。務必落實密碼雜湊、預處理、HTTPS、錯誤碼規範,才算合格的生產級登入 API。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved