【作业】为什么不试试神奇的Final Mission 呢?

【作业】为什么不试试神奇的Final Mission 呢?

panedioic
2019-11-06 / 0 评论 / 4 阅读 / 正在检测是否收录...

前言-关于为什么会有这篇文章

那当然是因为我想要水篇文章啦
咳咳,还不是因为某个Final Mission,写完了当然来水一篇文章咯(
1

关于前端

当写到这里的时候,忽然想起来之前做的某道web题的前端还行,于是就过来咯(x)

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Rabbit House 成员管理系统</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="content container pt-5">
        
    <h1>Rabbit House 成员管理系统</h1>
    <form method="post" action=".">
        <div class="form-group">
            <label>
                用户名:<input type="text" class="form-control" name="username">
            </label>
        </div>
        <div class="form-group">
            <label>
                密码:<input type="password" class="form-control" name="password">
            </label>
        </div>
        <button type="submit" class="btn btn-primary">登录</button>
    </form>
    </div>
</body>
</html>

数据库部分

考虑到这个项目的要求有登录,注销以及留言功能,所以需要用到数据库。我建立的数据表结构如下:

首先建一个final_database来存放这个项目的数据。

final_user 结构如下:


username显然是用户的id,password用来保存用户的密码,按照需要也可以保存密码的md5,head_path保存用户的头像路径。

msg_book 结构如下:


username是用户id,post_time保存用户留言的时间,text是用户留言的内容,最后的post_time是偷个懒,用户留言时直接把头像路径保存,略去输出用户留言时再去查询头像。

user_auth 结构如下:


username是用户id,再用户登陆时会随机生成一串数字作为验证,随机数保存于userauth,登陆时间保存于authtime

项目包含文件

由于项目各个模块基本都要用到cookie,mysql查询等功能,为了提高代码的复用率,所以这些代码写到一个文件,各个部分再包含这个文件。

常量定义

//Contest definations.
define("MYSQL_HOST", "**.**.**.**");
define("MYSQL_USERNAME", "*********");
define("MYSQL_PASSWORD", "********");
define("MYSQL_DATABASE", "final_database");
//我的mysql怎么可能放在这呢(

define("TABLE_USERLIST", "final_user");
define("TABLE_MSGBOOK", "msg_book");
define("TABLE_USERAUTH", "user_auth");

cookie部分

//Cookie control
// 开启Session
session_start();

$isLogin = false;
if(isset($_COOKIE['username'])){
    $isLogin=true;
    $user_name = $_COOKIE['username'];
    $head_path = $_COOKIE['headpath'];
    $user_auth = $_COOKIE['userauth'];
}//把cookie的数据保存至变量方便后续使用
else{
    $isLogin=false;
}

mysql部分

//MySql Control
$link = mysqli_connect(MYSQL_HOST, MYSQL_USERNAME, MYSQL_PASSWORD, MYSQL_DATABASE);

MySql部分就相对比较简单了,后面需要查询的时候都是单独写的。。

防XSS攻击模块

由于用户的id和留言内容都是直接使用用户提交的字符串,就存在xss攻击的风险,所以要对用户提交的内容进行过滤。

function anti_xss($text){
    $text_anti_xss = trim($text);  //清理空格  
    $text_anti_xss = strip_tags($text_anti_xss);   //过滤html标签  
    $text_anti_xss = htmlspecialchars($text_anti_xss);   //将字符内容转化为html实体  
    $text_anti_xss = addslashes($text_anti_xss);  //防止SQL注入
    return $text_anti_xss;
}

用户登录验证模块

在用户登录之后发表信息的时候验证用户身份的部分,,,emm算了不描述了(

function auth_check($auth, $name, $link){
    $sql = "SELECT * FROM `".TABLE_USERAUTH."` WHERE username = '$name'";
    $res = mysqli_query($link, $sql);
    $arr = mysqli_fetch_assoc($res);
    if($arr){
        if($arr['userauth']==$auth && $arr['authtime'] + 3600 > time()){
            return 1;
        }
        else {
            return 0;
        }
    }
    else {
        return -1;
    }
}

function auth_insert($auth, $name, $link){
    //Check that user authentication exists.
        $tmp = auth_check($auth, $name, $link);
        if($tmp >= 0){
            $sql2 = "UPDATE `user_auth` SET `userauth` = '$auth', `authtime` = '".time()."' WHERE `user_auth`.`username` = '$name'";
            mysqli_query($link, $sql2);
        }
        else if($tmp == -1){
            $sql2 = "INSERT INTO `".TABLE_USERAUTH."` (`username`, `userauth`, `authtime`) VALUES ('$name', '$auth', '".time()."')";
            mysqli_query($link, $sql2);
        }    
}

具体讲解之后再补吧emm

用户登录部分设计

function user_login($username, $password, $link){
    $sql = "SELECT * FROM `final_user` WHERE username = '$username'";
    $res = mysqli_query($link, $sql);
    $arr = mysqli_fetch_assoc($res);
    $password_md5ed = md5($password);
    if($arr){
        if($arr['password']==$password_md5ed){
            $auth_tmp = rand(1000000,9999999);
            setcookie("username",$_POST["username"],time()+3600);
            setcookie("headpath",$arr["head_path"],time()+3600);
            setcookie("userauth",$auth_tmp,time()+3600);
            auth_insert($auth_tmp, $username, $link);
            echo"<script>alert('登录成功!');location.href = 'index.php';</script>";
        }else{
            echo"<script>alert('密码错误!');location.href = 'index.php';</script>";
        }
    }else{
        echo "<script>alert('".$username."');</script>";
        echo"<script>alert('用户名不存在,请先注册!');location.href = 'index.php';</script>";
    }
}

在收到用户的登录请求时,通过提交的用户名查询到密码的md5值,然后再将密码md5之后进行比较。登录成功后进行cookie的设置和用户auth信息的更新。

用户注册部分设计

function user_register($username, $password, $link){
    $username_anti_xss = anti_xss($username);
    $sql = "SELECT * FROM `".TABLE_USERLIST."` WHERE username = '$username_anti_xss'";
    $res = mysqli_query($link, $sql);
    $arr = mysqli_fetch_assoc($res);
    if($arr){
        echo"<script>alert('用户名已存在!');location.href = 'index.php';</script>";
    }else{
        $password_md5ed = md5($password);
        $sql2 = "INSERT INTO `".TABLE_USERLIST."` (`username`, `password`, `head_path`) VALUES ('$username_anti_xss', '$password_md5ed', NULL)";
        mysqli_query($link, $sql2);
        echo"<script>alert('注册成功!');location.href = 'index.php';</script>";
    }
}

和用户登录部分大体一致

用户登出部分设计

function user_logout(){
    setcookie("username",$user_name,time()-3600);
    setcookie("headpath",$head_path,time()-3600);
    setcookie("userauth",$user_auth,time()-3600);
    echo "<script>alert('注销成功!');location.href = 'index.php';</script>";
}

在用户登出时删除所有cookie,还应该更新下用户的auth信息的,之后再补吧emmm

发布留言部分设计

function post_msg($text, $username, $headpath, $link){
    $text_anti_xss = anti_xss($text);
    $sql2 = "INSERT INTO `".TABLE_MSGBOOK."` (`username`, `post_time`, `text`, `post_head`) VALUES ('$username', CURRENT_TIMESTAMP, '$text_anti_xss', '$headpath')";
    mysqli_query($link, $sql2);
    echo"<script>alert('发送成功!');location.href = 'index.php';</script>";
}

代码言简意赅,就这样吧(

上传头像部分设计

function post_img($img, $username, $link){
      // 服务器中文件的存放目录
  $tmp_dir=$img['tmp_name'];
  //用户上传的文件名(带后缀)
  $fileName=$img['name'];
 
  if($img['error']!=0){
     echo '上传文件出现错误!请重试!';
     return;
  }else if($img['size']>10240000){
     echo "文件超过".$maxSize;
     return;
  }else if($img['size']<20480){
    echo "上传文件出现错误!请重试!";
    return;
 }else{
    //创建目录
    $fileDir='./upload/';
    if(!is_dir($fileDir)){
        mkdir($fileDir);
    }
    //文件名
    $newFileName=date('YmdHis',time()).rand(100,999);
    //文件后缀
    $FileExt=substr($fileName,strrpos($fileName,'.'));
    $FilePath=$newFileName.$FileExt;

    //生成缩略图
    $img_info=getimagesize($tmp_dir);
    // var_dump($img_info);
    $width=$img_info[0]; //原图的宽
    $height=$img_info[1]; //原图的高
    $newWidth=$width*0.5;
    $newHeight=$height*0.5;

    //绘制画布
    $thumb=imagecreatetruecolor($newWidth, $newHeight);
    //创建一个和原图一样的资源
    $source=imagecreatefromjpeg($tmp_dir);

    //根据原图创建缩略图
    imagecopyresized($thumb,$source,0,0,0,0,$newWidth,$newHeight,$width,$height);

    //保存缩略图
    imagejpeg($thumb,'./upload/'.$newFileName.$FileExt,100);

    //移动文件到指定的目录
    move_uploaded_file($tmp_dir,'./upload/'.$newFileName.'_temp'.$FileExt);
    unlink('./upload/'.$newFileName.'_temp'.$FileExt);
    $sql2 = "update final_user set `head_path`='$FilePath' WHERE username = '$username'";
    mysqli_query($link, $sql2);
    setcookie("headpath",$FilePath,time()+3600);
    echo "<script>alert('上传成功!');location.href = 'index.php';</script>";
    
  }
}

为了避免文件上传存在的风险,于是选择在用户上传图片后进行压缩,从而避免文件上传的风险。


接下来就是各个部分的前端了

首页部分 index.php

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Rabbit 留言本 ^ - ^</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="content container pt-5">
        
    <h1>Rabbit 留言本 ^ - ^</h1>
    <p>本站提供注册,登录,留言板功能!</p>
    <?php
    include "include.php";
    if ($isLogin) {
        // 若已经登录
        //输出用户信息
        echo "你好! ".$user_name.' ,欢迎来到个人中心!<br>';
        echo "<img src=\"./upload/$head_path\" width=50 height=50> ";
        echo "<a class=\"btn btn-warning\" href='logout.php'>注销</a> ";
        echo "<a class=\"btn btn-warning\" href='upimg.html'>上传/修改头像</a>";
    } else {
        // 若没有登录
        echo "您还没有登录,请先登录!</a>";
    }
 ?>
    <form method="post" action="login.php" <?php if ($isLogin)echo "hidden"?>>
        <div class="form-group">
            <label>
                用户名:<input type="text" class="form-control" name="username">
            </label>
        </div>
        <div class="form-group">
            <label>
                密码:<input type="password" class="form-control" name="password">
            </label>
        </div>
        <button type="submit" class="btn btn-primary">登录</button>
        <a class="btn btn-success" href="register.php">没有id?点击注册</a>
    </form>
    <div id="loged"  <?php if (!$isLogin)echo "hidden"?>>
        <p>test233</p>
        <table border="1" width=80%>
            <tr>
                <td>Test</td>
                <td width=80%>test message</td>
            </tr>
            <?php //输出留言信息
                $query='select * from msg_book';
                $result=mysqli_query($link, $query);
                
                //echo '<br> <br>';
                
                while ($data=mysqli_fetch_assoc($result)){
                echo '<tr>';
                echo '<td>';
                echo "<img src=\"./upload/".$data[post_head]."\" width=50 height=50> <br> $data[username] <br> ";
                echo $data[post_time];
                echo '</td>';
                echo '<td>'.$data[text].'</td>';
                //echo '</tr>\n'
                }
            
            ?>
            <tr>
                <td>Admin<br>2019-11-3 22:45</td>
                <td width=80%>Welcome!</td>
            </tr>
            <tr>
                <td colspan="2">
                <form name="input" action="postmsg.php" method="post">
                    回复内容: <input type="text" name="text">
                    <input type="submit" value="Submit">
                    </form>
                </td>
            </tr>
        </table>
    </div>
    <br>
    <p>本站仅供学习使用,请勿用于任何非法用途!<del>更不要日站!!!</del></p>

    </div>
</body>
</html>

判断用户是否登录来对对部分内容进行隐藏,中间通过查询留言本按照表格输出数据。

注册页面 register.php

(注:后面html部分基本相同所以只写body部分了。。)

<?php
        header('content-type:text/html;charset=utf-8');
        include "include.php";
        //检测用户是否登录
        if ($isLogin) {
            echo"<script>alert('您已经登录请不要重复注册!');location.href = 'index.php';</script>";
        }


        if(isset($_POST['username'])){
            $name = $_POST["username"];
            $pwd = $_POST["password"];
            user_register($name, $pwd, $link);
        }
    ?>

登录页面 login.php

<?php
header('content-type:text/html;charset=utf-8');
include "include.php";
//检测用户是否登录
if ($isLogin) {
    echo"<script>alert('您已经登录请不要重复登录!');location.href = 'index.php';</script>";
}


//接受客户端的数据:
$name = $_POST["username"];
$pwd = $_POST["password"];
user_login($name, $pwd, $link);
?>

登出页面 louout.php

<?php
    header('content-type:text/html;charset=utf-8');
    include "include.php";
    user_logout();
?>

发布留言页面 postmsg.php

<?php
header('content-type:text/html;charset=utf-8');
include "include.php";
//检测用户是否登录
if (!$isLogin) {
    echo"<script>alert('您还没有登录!');location.href = 'index.php';</script>";
    exit();
}
//检测认证信息
if(auth_check($user_auth, $user_name, $link)!=1){
    echo"登陆信息出错,信息提交失败!";
    exit();
}


//接受客户端的数据:
$text = $_POST["text"];
$name = $_COOKIE["username"];
$hdpath=$_COOKIE['headpath'];

post_msg($text, $name, $hdpath, $link);
?>

上传头像页面

upimg.html

<body>
  <p>建议上传jpg格式图片。</p>
<form action="upImg.php" method="post" enctype="multipart/form-data">
  <input type="file" name="userImg" >
  <input type="submit" value="上传">
</form>

upimg.php

<?php
  header('content-type:text/html;charset=utf-8');
  date_default_timezone_set("PRC");
  include "include.php";
 
  $img=$_FILES['userImg'];
  
  post_img($img, $user_name, $link);
?>

之后,是这个项目的一些参考:
PHP上传用户头像及头像的缩略图
PHP防XSS攻击
b站之前学php的视频(的笔记)


项目已上传至github,欢迎一起来玩鸭~
https://github.com/panedioic/rabbit_msgbook

0

评论 (0)

取消