项目方案(基本都是废话可以跳过)

《个人社工库网站》毕业设计项目方案

一、项目背景与目标

随着网络应用的普及,搭建一个高效、稳定的Web应用开发环境显得尤为重要。本项目旨在开发一个基于LNMP(Linux、Nginx、MySQL、PHP)架构的个人社工库查询系统,提供用户信息查询功能,同时锻炼开发者的综合技术能力.

二、开发环境搭建与配置

1. 系统选择

操作系统:CentOS 7

环境架构:LNMP

2. 环境搭建步骤

更换yum源为阿里云源,安装wget、nginx、PHP及其组件,并配置nginx和PHP

安装MariaDB,初始化数据库并设置远程访问权限

三、数据库设计

采用Mariadb作为数据库

students_init数据库:创建Personal_info表,存储个人信息

web_users_init数据库:创建users_info表,存储用户登录信息

四、网页设计

登录页面:实现用户登录功能,使用HTML、JavaScript和AJAX

查询页面:提供个人信息查询功能,使用HTML、CSS和JavaScript

五、后端开发

用户登录验证:使用PHP脚本验证用户名和密码

盐值获取:为前端提供用户盐值

登录状态检查:检查用户是否已登录

登出功能:销毁会话信息

信息查询:根据姓名查询个人信息

本项目为个人项目

项目实战

开发环境搭建与配置

方案一 LNMP

系统:CentOS7

CentOS7负责MariaDB、PHP和Nginx

方案二 LM WAP

系统:CentOS7和Windows10

CentOS7负责mysql数据库

Windows10负责PHP和Apache2.0

环境搭建部分

#测试通信
curl www.baidu.com
#拷贝yum源
cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
#下载wget
yum install wget* -y
#更换阿里云的yum源
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
yum clean all  #清理yum缓存
yum makecache  #更新yum缓存
yum repolist   #显示yum仓库
#配置nginx文件
vi /etc/yum.repos.d/nginx.repo
-----------------------------------
[nginx] 
name = nginx repo 
baseurl = https://nginx.org/packages/mainline/centos/7/$basearch/ 
gpgcheck = 0 
enabled = 1
-----------------------------------
#安装nginx
yum install -y nginx
#拷贝配置文件
cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.backup
#编辑替换原有配置内容
vim /etc/nginx/conf.d/default.conf
-----------------------------------
server {
 listen       80;
 root   /usr/share/nginx/html;
 server_name  localhost;
 #charset koi8-r;
 #access_log  /var/log/nginx/log/host.access.log  main;
 #
 location / {
       index index.php index.html index.htm;
 }
 #error_page  404              /404.html;
 #redirect server error pages to the static page /50x.html
 #
 error_page   500 502 503 504  /50x.html;
 location = /50x.html {
   root   /usr/share/nginx/html;
 }
 #pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
 #
 location ~ .php$ {
   fastcgi_pass   127.0.0.1:9000;
   fastcgi_index  index.php;
   fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
   include        fastcgi_params;
 }
}
-----------------------------------
#下载epel和remi的rpm源
yum -y install http://47.121.128.98:8090/upload/epel-release-latest-7.noarch.rpm
yum -y install https://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum -y install yum-utils                    #下载yum管理工具
yum-config-manager --disable 'remi-php*'    #删去默认remi-php版本
yum-config-manager --enable remi-php80      #替换为remi-php80版本
#下载php以及其他php组件
yum -y install php php-{cli,fpm,mysqlnd,zip,devel,gd,mbstring,curl,xml,pear,bcmath,json}
php -v                      #查看php版本检查安装结果
systemctl start php-fpm     #启动php管理工具
systemctl enable php-fpm    #设置自动启动php管理工具

cd /usr/share/nginx/html/  
touch index.php

echo "<?php phpinfo(); ?>" >> /usr/share/nginx/html/index.php  #用于验证php是否生效
systemctl start nginx       #启动nginx
systemctl enable nginx      #设置自动启动nginx
yum -y install mariadb-server    #下载mariadb
systemctl start mariadb          #启动mariadb
systemctl enable mariadb         #设置自动启动mariadb
mysql_secure_installation        #初始化数据库
mysql -u root -p                 #登录数据库
#允许所有IP使用root账户远程登录数据库并刷新权限
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '817@Toor' WITH GRANT OPTION;
flush privileges;

数据库部分

登录数据库mysql -u username -p创建相关数据库和数据表

SHOW DATABASES;              #查询有哪些数据库

CREATE DATABASE students_init;

USE students_init;

CREATE TABLE Personal_info (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100),
    former_name VARCHAR(100),
    gender VARCHAR(10),
    nationality VARCHAR(50),
    birth_date DATE,
    native_place VARCHAR(255),
    education_level VARCHAR(100),
    political_status VARCHAR(100),
    contact_phone VARCHAR(20),
    email VARCHAR(100),
    id_card_number VARCHAR(18),
    household_register VARCHAR(255),
    postal_code1 CHAR(6),
    current_address VARCHAR(255),
    postal_code2 CHAR(6)
) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;


INSERT INTO Personal_info ( name, former_name, gender, nationality, birth_date, native_place, education_level, political_status, contact_phone, email, id_card_number, household_register, postal_code1, current_address, postal_code2 ) 
VALUES 
('王栎鑫', '无', '女', '汉族', '2001-2-12', '湖南省炎陵县', '高中', '中共党员', '18722260583', '2133387882@qq.com', '520201200102120123', '上海市浦东新区三林镇西林街777弄33号201室', '204124', '上海市浦东新区三林镇西林街777弄33号201室', '204124'), 
('张三丰', '无', '男', '汉族', '2002-12-26', '广东省广州市番禺区', '高中', '中共团员', '18733343818', '2644402332@qq.com', '310105200212265012', '上海市浦东新区三林镇西林街888弄44号302室', '200736', '上海市浦东新区三林镇西林街888弄44号302室', '200736'),
('齐豫天', '无', '女', '汉族', '2003-08-26', '上海市静安区', '高中', '群众', '18744408262', '无', '310108200308260047', '上海市浦东新区三林镇西林街999弄55号403室', '201070', '上海市浦东新区三林镇西林街999弄55号403室', '201070');

SELECT * FROM Personal_info;


CREATE DATABASE web_users_init;

use web_users_init;

CREATE TABLE users_info (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    salt VARCHAR(255) NOT NULL,
    password_hash VARCHAR(255) NOT NULL
);

INSERT INTO users_info (name, salt, password_hash) VALUES ('admin', 'adminroot', 'd688ffccf8a63c50998b00e38bece362c544800bcd8c5d5f3956420c3892969e');

网页部分

index.html默认页作为登录页

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login Page</title>
    <script src="jquery.min.js"></script>
    <script src="crypto-js.min.js"></script>
    
    <script>
        $(document).ready(function(){
            $('form').submit(function(e){
                e.preventDefault(); // 阻止表单默认提交行为
                var username = $('input[name="username"]').val();
                var password = $('input[name="password"]').val();

                // 获取盐值
                $.get('getSalt.php', {username: username}, function(data){
                    var response = JSON.parse(data);
                    if(response.success){
                        var salt = response.salt;
                        var encryptedPassword = CryptoJS.SHA256(password + salt).toString();
                        $('#encryptedPassword').text('Encrypted Password: ' + encryptedPassword);
                        $.post('login.php', {username: username, password: encryptedPassword}, function(data){
                            console.log(data); // 检查返回的数据
                            var response = JSON.parse(data);
                            if(response.success){
                                alert('登陆成功');
                                console.log('Login successful, redirecting...'); 
                                setTimeout(function(){
                                    window.location.href = 'show.html'; // 成功则跳转到show.html
                                }, 500); // 延迟0.5秒跳转
                            } else {
                                alert('用户名或密码错误');
                            }
                        });
                    } else {
                        alert('用户名不存在');
                    }
                });
            });
        });
    </script>
</head>
<body>
    <h2>Login Page</h2>
    <form>
        Username: <input type="text" name="username" required><br>
        Password: <input type="password" name="password" required><br>
        <input type="submit" value="Login">
    </form>
    <div id="encryptedPassword"></div> <!-- 用于显示加密后的密码 -->
</body>
</html>

show.html作为查询页

<!DOCTYPE html>
<html>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="jquery.min.js"></script>
    <script>
        $(document).ready(function() {
            $.get("checkLogin.php", function(data) {
                if (!data.loggedIn) {
                    window.location.href = "index.html";
                }
            }).fail(function() {
                console.log("Failed to check login status");
            });
        });
    </script>
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var timeoutId = setTimeout(function() {
                console.log("Session timeout, redirecting to login page...");
                window.location.href = 'index.html'; // 直接重定向到登录页面
            }, 600000); // 10分钟后执行
        
            // 重置计时器的事件
            document.addEventListener("mousemove", function() {
                clearTimeout(timeoutId);
                timeoutId = setTimeout(function() {
                    console.log("Session timeout, redirecting to login page...");
                    window.location.href = 'index.html'; // 直接重定向到登录页面
                }, 600000); // 重新设置10分钟计时器
            });
        });
    </script>

<head>
    <title>个人社工库查询系统</title>
    <style>
        table {
            border-collapse: collapse;
            /* 使边框合并为一个单一的边框 */
            margin-left: auto;
            /* 左外边距设置为自动 */
            margin-right: auto;
            /* 右外边距设置为自动 */
            /* 以下样式为表格添加了一些基本的样式 */
            border: 1px solid #000;
            justify-content: center; /* 水平居中 */
            align-items: center; /* 垂直居中 */
            font-family: 'SimSun', '宋体', serif; /* 设置字体为宋体 */
        }

        td,th {
            
            /* 设置列宽为3.6厘米 */
            height: 0.6cm;
            border: 1px solid black;
            /* 设置边框样式 */
            text-align: center; /* 文本居中 */
            font-family: 'SimSun', serif; /* 设置字体为宋体 */
            
            padding: 2px; /* 单元格内边距 */
        }

        .wulie{
            width: 3.4cm;/* 填空处列宽 */
        }

        .tiankong{
            width: 3.8cm;/* 填空处列宽 */
            font-size: 10pt; /* 设置字体大小,这里用像素单位,可以根据需要调整 */
        }

        .biaoming{
            width: 3.4cm; /* 表中单元格名称 */
            font-weight: bold;
            font-size: 12pt; /* 设置字体大小,这里用像素单位,可以根据需要调整 */
            background-color: #dfdfdf;
            
        }

        .dygname{
            font-weight: bold; /* 设置文本为粗体 */
            font-size: 12pt; /* 设置字体大小为26磅 */
            
        }


        /* 设置输入框和按钮的基本样式 */
        input[type="text"] {
            padding: 8px;
            margin: 5px;
            border: 1px solid #ccc;
            border-radius: 4px;
        }

        input[type="submit"] {
            padding: 8px 15px;
            margin: 5px;
            border: none;
            border-radius: 4px;
            background-color: #007bff;
            color: white;
            cursor: pointer;
        }

        input[type="submit"]:hover {
            background-color: #0056b3;
        }

        .sousuolan{
            margin-left: auto;
            /* 左外边距设置为自动 */
            margin-right: auto;
            /* 右外边距设置为自动 */
            width: 7.6cm;
        }
    </style>
</head>

<body>
    <form id="searchForm" method="POST" action="search.php">
        <label for="searchName">姓名:</label>
        <input type="text" id="searchName" name="searchName" required>
        <button type="submit">搜索</button>
        <button onclick="location.href='logout.php'">登出</button>
    </form>
    

    <table id="infoTable" border="1">
        <tr>
            <td class="biaoming">姓&nbsp;&nbsp;名</td>
            <td id="name" class="tiankong"></td>
            <td class="biaoming">曾用名</td>
            <td id="former_name" class="tiankong"></td>
            <td rowspan="6" id="photo" class="wulie">照片</td>
        </tr>
        <tr>
            <td class="biaoming">性&nbsp;&nbsp;别</td>
            <td id="gender" class="tiankong"></td>
            <td class="biaoming">民&nbsp;&nbsp;族</td>
            <td id="nationality" class="tiankong"></td>
        </tr>
        <tr>
            <td class="biaoming">出生日期</td>
            <td id="birth_date" class="tiankong"></td>
            <td class="biaoming">籍&nbsp;&nbsp;贯</td>
            <td id="native_place" class="tiankong"></td>
        </tr>
        <tr>
            <td class="biaoming">文化程度</td>
            <td id="education_level" class="tiankong"></td>
            <td class="biaoming">政治面貌</td>
            <td id="political_status" class="tiankong"></td>
        </tr>
        <tr>
            <td class="biaoming">联系电话</td>
            <td id="contact_phone" class="tiankong"></td>
            <td class="biaoming">电子邮箱</td>
            <td id="email" class="tiankong"></td>
        </tr>
        <tr>
            <td class="biaoming">居民身份证号</td>
            <td colspan="3" id="id_card_number" class="tiankong"></td>
        </tr>
        <tr>
            <td class="biaoming">户籍所在地</td>
            <td colspan="2" id="household_register" class="tiankong"></td>
            <td rowspan="2" class="biaoming">邮政编码</td>
            <td id="postal_code" class="wulie"></td>
        </tr>
        <tr>
            <td class="biaoming">现居住地址</td>
            <td colspan="2" id="current_address" class="tiankong"></td>
            <td id="current_postal_code" class="wulie"></td>
        </tr>
    </table>


    <script>
        document.getElementById('searchForm').onsubmit = function(event) {
            event.preventDefault(); // 阻止默认表单提交

            const searchName = document.getElementById('searchName').value;

            fetch('search.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: 'searchName=' + encodeURIComponent(searchName)
            })
            .then(response => response.json())
            .then(data => {
                if (data.length === 0) {
                    alert('未找到相关信息');
                    return;
                }

                // 假设只返回一条记录,这里填充表格
                const userInfo = data[0];
                document.getElementById('name').innerText = userInfo.name || '';
                document.getElementById('former_name').innerText = userInfo.former_name || '';
                document.getElementById('gender').innerText = userInfo.gender || '';
                document.getElementById('nationality').innerText = userInfo.nationality || '';
                document.getElementById('birth_date').innerText = userInfo.birth_date || '';
                document.getElementById('native_place').innerText = userInfo.native_place || '';
                document.getElementById('education_level').innerText = userInfo.education_level || '';
                document.getElementById('political_status').innerText = userInfo.political_status || '';
                document.getElementById('contact_phone').innerText = userInfo.contact_phone || '';
                document.getElementById('email').innerText = userInfo.email || '';
                document.getElementById('id_card_number').innerText = userInfo.id_card_number || '';
                document.getElementById('household_register').innerText = userInfo.household_register || '';
                document.getElementById('postal_code').innerText = userInfo.postal_code1 || '';
                document.getElementById('current_address').innerText = userInfo.current_address || '';
                document.getElementById('current_postal_code').innerText = userInfo.postal_code2 || '';

                // 如果有照片字段,可以动态设置图片
                if (userInfo.photo_url) {
                    const photoCell = document.getElementById('photo');
                    photoCell.innerHTML = `<img src="${userInfo.photo_url}" alt="照片" style="width:100%;height:auto;">`;
                }
            })
            .catch(error => console.error('请求出错:', error));
        };
        </script>


</body>

</html>

login.php作为登录校验和用于存储登陆状态的

<?php
session_start();
ini_set('session.gc_maxlifetime', 600); // 设置会话超时时间为10分钟
$host = '192.168.71.240';
$dbUsername = 'root';
$dbPassword = '817@Toor';
$dbName = 'web_users_init';

$username = $_POST['username'];
$password = $_POST['password'];

// 创建数据库连接
$conn = new mysqli($host, $dbUsername, $dbPassword, $dbName);

// 检查连接
if ($conn->connect_error) {
    die(json_encode(array("success" => false, "error" => "Connection failed: " . $conn->connect_error)));
}

$sql = "SELECT password_hash FROM users_info WHERE name = '$username'";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    $row = $result->fetch_assoc();
    // 这里比较的是加密后的密码,确保前端发送的是加密后的密码
    if ($row['password_hash'] === $password) {
        $_SESSION['loggedin'] = true; // 设置会话变量
        $_SESSION['username'] = $username; // 可选:存储用户名
        echo json_encode(array("success" => true));
    } else {
        echo json_encode(array("success" => false, "error" => "Password mismatch"));
    }
} else {
    echo json_encode(array("success" => false, "error" => "User not found"));
}
$conn->close();
?>

getSalt.php用于获取后端数据库盐加密的盐值

<?php
$host = '192.168.71.240';
$dbUsername = 'root';
$dbPassword = '817@Toor';
$dbName = 'web_users_init';

// 创建数据库连接
$conn = new mysqli($host, $dbUsername, $dbPassword, $dbName);

// 检查连接
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

$username = $_GET['username'];
$sql = "SELECT salt FROM users_info WHERE name = '$username'";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    $row = $result->fetch_assoc();
    echo json_encode(array("success" => true, "salt" => $row['salt']));
} else {
    echo json_encode(array("success" => false, "error" => "User not found"));
}
$conn->close();
?>

checkLogin.php用于检查登陆状态

<?php
session_start();
header('Content-Type: application/json');

if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
    echo json_encode(array("loggedIn" => true));
} else {
    echo json_encode(array("loggedIn" => false));
}
?>

logout.php用于退出登录状态

<?php
session_start();

// 销毁所有会话变量
$_SESSION = array();

// 如果使用基于 cookie 的会话,也要销毁 cookie
if (ini_get("session.use_cookies")) {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 600,
        $params["path"], $params["domain"],
        $params["secure"], $params["httponly"]
    );
}

// 最后,销毁会话
session_destroy();
// 重定向到登录页面
header("Location: index.html");
exit;
?>

search.php用于查询数据库中个人信息

<?php
$config = require 'conf.php'; // 引入配置文件
$con = mysqli_connect($config['db_host'], $config['db_user'], $config['db_pass'], $config['db_name']);

if (mysqli_connect_errno()) {
    echo json_encode(["error" => "Failed to connect to MySQL: " . mysqli_connect_error()]);
    exit();
}

$searchName = isset($_POST['searchName']) ? mysqli_real_escape_string($con, $_POST['searchName']) : null;

if ($searchName !== null) {
    $query = "SELECT * FROM Personal_info WHERE name LIKE '%$searchName%'";
    $result = mysqli_query($con, $query);

    $data = [];
    if ($result) {
        while ($row = mysqli_fetch_assoc($result)) {
            $data[] = $row;
        }
    }

    header('Content-Type: application/json');
    echo json_encode($data);
} else {
    echo json_encode(["error" => "No search term provided"]);
}

mysqli_close($con);
?>

conf.php用于存放数据库相关重要信息

<?php
// conf.php
return [
    'db_host' => '192.168.71.240',
    'db_user' => 'root',
    'db_pass' => '817@Toor',
    'db_name' => 'students_init',
];
?>