11. MYSQL数据库

一、MySQL 基础概念

  1. 数据库(Database)
    • 用于存储结构化数据的容器,例如你的用户信息、文章数据等。
  2. 表(Table)
    • 数据按表组织,类似 Excel 表格,包含行(记录)和列(字段)。
    • 例如:用户表 users 可能有字段 id, username, password, email
  3. SQL(Structured Query Language)
    • 操作数据库的标准语言,用于增删改查(CRUD)。

二、CentOS7 安装 MySQL

  1. 安装 MySQL

    # CentOS7 默认使用 MariaDB(MySQL 分支)
    yum install mariadb-server mariadb
    systemctl start mariadb
    systemctl enable mariadb  # 开机自启
    
  2. 初始化安全设置

    mysql_secure_installation
    
    • 设置 root 密码、删除匿名用户、禁止远程 root 登录等。

三、MySQL 基础操作

1. 登录 MySQL

mysql -u root -p

2. 创建数据库和表(以用户表为例)

-- 创建数据库
CREATE DATABASE web_login;

-- 使用数据库
USE web_login;

-- 创建用户表(关键!)
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,  -- 存储哈希值,非明文密码!
    email VARCHAR(100),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

3. 常用 SQL 语句

-- 创建表
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    password_hash CHAR(32) NOT NULL,  -- MD5 固定 32 字符
    email VARCHAR(100)
);

-- 插入数据
INSERT INTO users (username, password_hash, email)
VALUES ('john', MD5('123456'), 'john@xiandai.com');

-- 验证密码(简单示例,实际不推荐!)
SELECT * FROM users 
WHERE username = 'john' AND password_hash = MD5('输入密码');

-- 删除用户
DELETE FROM users WHERE id = 1;

四、MD5 的解释

  1. MD5 是什么?

    • MD5(Message-Digest Algorithm 5)是一种广泛使用的哈希函数,生成 128 位(32 字符)的哈希值。
    • 例如:MD5('password')5f4dcc3b5aa765d61d8327deb882cf99
  2. 为什么现在不推荐用 MD5 存储密码?

    • 安全性低
      • MD5 已被证明存在碰撞漏洞(不同输入生成相同哈希值)。
      • 容易被暴力破解或彩虹表(预先计算的哈希字典)攻击。
    • 无盐值(Salt)
      • MD5 本身不包含随机盐值,多个用户相同密码的哈希值会重复,易被批量破解。
  3. 什么情况下可以用 MD5?

    • 仅用于非敏感数据的快速校验(如文件完整性检查)。
    • 绝不建议用于密码存储

五、代码

index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <style>
        /* 基础样式重置 */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: #f0f2f5;
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        /* 登录容器 */
        .login-container {
            background: white;
            padding: 2.5rem;
            border-radius: 10px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            width: 100%;
            max-width: 400px;
        }

        /* 标题样式 */
        h1 {
            color: #1a73e8;
            text-align: center;
            margin-bottom: 2rem;
            font-size: 1.8rem;
        }

        /* 表单组样式 */
        .form-group {
            margin-bottom: 1.5rem;
        }

        label {
            display: block;
            margin-bottom: 0.5rem;
            color: #5f6368;
            font-weight: 500;
        }

        input {
            width: 100%;
            padding: 12px;
            border: 1px solid #dadce0;
            border-radius: 5px;
            font-size: 1rem;
            transition: border-color 0.3s ease;
        }

        input:focus {
            outline: none;
            border-color: #1a73e8;
            box-shadow: 0 0 0 2px rgba(26,115,232,0.2);
        }

        /* 登录按钮 */
        .login-btn {
            width: 100%;
            padding: 12px;
            background: #1a73e8;
            color: white;
            border: none;
            border-radius: 5px;
            font-size: 1rem;
            cursor: pointer;
            transition: background 0.3s ease;
        }

        .login-btn:hover {
            background: #1557b0;
        }

        /* 错误提示 */
        .error-msg {
            color: #dc3545;
            font-size: 0.875rem;
            margin-top: 0.5rem;
            display: none;
        }

        /* 底部链接 */
        .bottom-links {
            text-align: center;
            margin-top: 1.5rem;
        }

        .bottom-links a {
            color: #1a73e8;
            text-decoration: none;
            font-size: 0.875rem;
        }

        .bottom-links a:hover {
            text-decoration: underline;
        }
    </style>
</head>
<body>
    <div class="login-container">
        <h1>用户登录</h1>
  
   
        <form id="loginForm" action="login.php" method="POST">
            <div class="form-group">
                <label for="username">用户名</label>
                <input 
                    type="text" 
                    id="username" 
                    name="username" 
                    placeholder="请输入用户名"
                    required
                >
                <div class="error-msg" id="usernameError">用户名不能为空</div>
            </div>

            <div class="form-group">
                <label for="password">密码</label>
                <input 
                    type="password" 
                    id="password" 
                    name="password" 
                    placeholder="请输入密码"
                    required
                    minlength="6"
                >
                <div class="error-msg" id="passwordError">密码不能少于6位</div>
            </div>

            <button type="submit" class="login-btn">登录</button>
        </form>

        <div class="bottom-links">
            <a href="#">忘记密码?</a>
            <span style="color: #dadce0"> | </span>
            <a href="#">立即注册</a>
        </div>
    </div>

    <script>
        const form = document.getElementById('loginForm');
        const usernameInput = document.getElementById('username');
        const passwordInput = document.getElementById('password');
        const usernameError = document.getElementById('usernameError');
        const passwordError = document.getElementById('passwordError');

        form.addEventListener('submit', function(e) {
            let isValid = true;

            if(usernameInput.value.trim() === '') {
                usernameError.style.display = 'block';
                isValid = false;
            }

            if(passwordInput.value.length < 6) {
                passwordError.style.display = 'block';
                isValid = false;
            }

     
            if(!isValid) {
                e.preventDefault();
            }
            // 验证通过时允许直接提交到PHP
        });
    </script>
</body>
</html>

config.php

<?php
$host = "localhost";
$user = "root";
$password = "";
$dbname = "web_login";

// 创建不安全连接
$conn = mysqli_connect($host, $user, $password, $dbname);

// 检查连接(显示详细错误)
if (!$conn) {
    die("连接失败: " . mysqli_connect_error());
}
?>

login.php

<?php
include 'config.php';

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // 直接获取用户输入,不做任何过滤
    $username = $_POST['username'];
    $password = $_POST['password'];

    // 构建危险SQL查询语句
    $sql = "SELECT * FROM users WHERE username='$username' AND password_hash=md5('$password')";
  
    // 执行查询(显示错误信息)
    $result = mysqli_query($conn, $sql);

    // 验证登录
    if (mysqli_num_rows($result) > 0) {
        // 登录成功跳转
        header("Location: dashboard.php?username=".$username);
        exit();
    } else {
        echo "用户名或密码错误!";
    }
}
?>

dashboard.php

<?php
// 注意:仍然没有会话验证和过滤
$username = $_GET['username']; // 直接从URL获取用户名
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>用户仪表盘</title>
    <style>
        /* 现代仪表盘样式 */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', system-ui;
        }

        body {
            background: #f0f2f5;
            min-height: 100vh;
        }

        .dashboard-container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 2rem;
        }

        .header {
            background: #1a73e8;
            color: white;
            padding: 1.5rem;
            border-radius: 12px;
            margin-bottom: 2rem;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
        }

        .welcome-text {
            font-size: 2rem;
            margin-bottom: 0.5rem;
        }

        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 1.5rem;
            margin-bottom: 2rem;
        }

        .stat-card {
            background: white;
            padding: 1.5rem;
            border-radius: 12px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.05);
            transition: transform 0.2s;
        }

        .stat-card:hover {
            transform: translateY(-2px);
        }

        .card-title {
            color: #5f6368;
            margin-bottom: 1rem;
            font-size: 0.9rem;
        }

        .card-value {
            font-size: 2rem;
            color: #1a73e8;
            font-weight: bold;
        }

        .recent-activity {
            background: white;
            border-radius: 12px;
            padding: 1.5rem;
            box-shadow: 0 2px 4px rgba(0,0,0,0.05);
        }

        .activity-list {
            list-style: none;
        }

        .activity-item {
            display: flex;
            align-items: center;
            padding: 1rem 0;
            border-bottom: 1px solid #eee;
        }

        .activity-icon {
            width: 40px;
            height: 40px;
            background: #1a73e820;
            border-radius: 8px;
            margin-right: 1rem;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #1a73e8;
        }
    </style>
</head>
<body>
    <div class="dashboard-container">
        <div class="header">
            <div class="welcome-text">欢迎回来,<?php echo $username; ?>!</div>
            <p>最后登录时间:2023-08-15 14:30</p>
        </div>

        <div class="stats-grid">
            <div class="stat-card">
                <div class="card-title">总访问量</div>
                <div class="card-value">2,345</div>
            </div>
            <div class="stat-card">
                <div class="card-title">新消息</div>
                <div class="card-value">12</div>
            </div>
            <div class="stat-card">
                <div class="card-title">账户余额</div>
                <div class="card-value">¥5,678</div>
            </div>
        </div>

        <div class="recent-activity">
            <h2>最近活动</h2>
            <ul class="activity-list">
                <li class="activity-item">
                    <div class="activity-icon">📌</div>
                    <div>
                        <h3>系统登录</h3>
                        <p>2023-08-15 14:30 从 192.168.1.1 登录</p>
                    </div>
                </li>
                <li class="activity-item">
                    <div class="activity-icon">💰</div>
                    <div>
                        <h3>收入到账</h3>
                        <p>+ ¥1,000 来自客户付款</p>
                    </div>
                </li>
                <li class="activity-item">
                    <div class="activity-icon">⚙️</div>
                    <div>
                        <h3>资料修改</h3>
                        <p>更新了个人联系方式</p>
                    </div>
                </li>
            </ul>
        </div>
    </div>
</body>
</html>