Open Lichen5221 opened 3 years ago
register.php 註冊頁面 handle_register.php 處理註冊邏輯 login.php 登入表單 handle_login.php 處理登入邏輯 logout.php 登出
只有註冊頁面 & 登入表單能看見,其他邏輯都在背後運作。
建立新的資料庫為使用者資料,並在資料庫欄位中新增 ID、nickname、username、password、created_at。
index.php 檔:
<?php
require_once("conn.php");
$result = $conn -> query("SELECT * FROM comments order by id desc");
if(!$result) {
die('Error:' . $conn -> error);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>留言板</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="warning">
<strong> 警告!有資安漏洞! </strong>
</header>
<main class="board">
<div>
<a class="board__btn" href="register.php">註冊</a>
<a class="board__btn" href="login.php">登入</a>
</div>
<h1 class="board__title">Comments</h1>
<?php
if(!empty($_GET['errCode'])) {
$code = $_GET['errCode'];
$msg = 'Error';
if ($code === '1') {
$msg = '錯誤:資料不齊全';
}
echo '<h2 class="error">' . $msg . '</h2>';
}
?>
<form class="board__new-comment-form"method="POST" action="handle_add_comment.php">
<div class="board__nickname">
<span>暱稱:</span>
<input type="text" name="nickname" />
</div>
<textarea name="content" rows="5"></textarea>
<input class="board__submit-btn"type="submit" />
</form>
<div class="board__hr"></div>
<section>
<?php
while($row = $result -> fetch_assoc()) {
?>
<div class="card">
<div class="card__avatar">
</div>
<div class="card__body">
<div class="card__info">
<span class="card__author">
<?php echo $row['nickname'];?>
</span>
<span class="card__time">
<?php echo $row['created_at'];?>
</span>
</div>
<p class="card__content"><?php echo $row['content']?></p>
</div>
</div>
<?php } ?>
</section>
</main>
</body>
</html>
CSS 檔:有些 index.php 已經不存在的我沒有刪掉,反正不影響。
body {
margin: 0;
background: #f7f7f7;
}
.warning {
background: #ffc4c6;
color: #a20606;
padding: 10px;
text-align: center;
}
.error {
color: red;
}
.board {
background: white;
width: 100%;
max-width: 700px;
margin: 20px auto;
padding: 10px 30px;
box-shadow: 1px 1px 3px #e8e8e8;
border-radius: 5px;
}
.board__btn {
padding: 10px 30px;
border: 1px solid #c2dffb;
border-radius: 5px;
color: black;
min-width: 20px;
font-size: 16px;
background: white;
text-decoration: none;
display: inline-block;
}
.board__new-comment-form textarea {
width: 100%;
padding: 10px;
border: 1px solid #c2dffb;
box-sizing: border-box;
}
.board__nickname {
margin-bottom: 10px;
}
.board__nickname input {
border: 1px solid #c2dffb;
padding: 5px;
}
.board__submit-btn {
padding: 10px;
border: 1px solid #c2dffb;
border-radius: 5px;
color: #583c63;
width: 100px;
font-size: 16px;
background: white;
}
.board__hr {
margin: 10px auto;
height: 2px;
background-color: #e8e8e8;
max-width: 95%;
}
.card {
margin: 20px 0;
min-height: 70px;
box-sizing: border-box;
display: flex;
}
.card__avatar {
min-width: 50px;
width: 50px;
height: 50px;
border-radius: 50%;
background: #e4f0fb;
}
.card__body {
margin-left: 10px;
}
.card__content {
margin-top: 8px;
max-width: 100%;
word-break: break-all;
white-space: pre-line; /* 換行效果 */
}
.card__author {
color: #5c9edc;
font-weight: bold;
}
.card__time {
color: #a0a0a0;
}
register.php 檔:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>註冊</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="warning">
<strong> 警告!有資安漏洞! </strong>
</header>
<main class="board">
<div>
<a class="board__btn" href="index.php">回留言板</a>
<a class="board__btn" href="login.php">登入</a>
</div>
<h1 class="board__title">註冊</h1>
<?php
if(!empty($_GET['errCode'])) {
$code = $_GET['errCode'];
$msg = 'Error';
if($code === '1') {
$msg = '錯誤:資料不齊全';
} else if ($code === '2') {
$msg = '錯誤:此帳號已有人使用';
}
echo '<h2 class="error">' . $msg . '</h2>';
}
?>
<form class="board__new-comment-form"method="POST" action="handle_register.php">
<div class="board__nickname">
<span>暱稱:</span>
<input type="text" name="nickname" />
</div>
<div class="board__nickname">
<span>帳號:</span>
<input type="text" name="username" />
</div>
<div class="board__nickname">
<span>密碼:</span>
<input type="password" name="password" />
</div>
<input class="board__submit-btn" type="submit" />
</form>
</main>
</body>
</html>
handle_register.php 檔:老師有另外一個用字串比對的方式跳轉錯誤訊息,但因為不常用且字串可能更改,所以我沒有將那個寫法放上來。
<?php
require_once('conn.php');
if (
empty($_POST['nickname']) ||
empty($_POST['username']) ||
empty($_POST['password'])
) {
header('Location: register.php?errCode=1');
die('資料不齊全');
}
$nickname = $_POST['nickname'];
$username = $_POST['username'];
$password = $_POST['password'];
$sql = sprintf(
"insert into users(nickname, username, password) values('%s', '%s', '%s')",
$nickname,
$username,
$password
);
$result = $conn->query($sql);
if (!$result) {
$code = $conn -> errno;
if($code === 1062) {
header('Location: register.php?errCode=2');
}
die($conn->error);
}
header("Location: index.php");
?>
$conn -> errno 一開始會出現白色頁面是因為他是跳轉錯誤數字,加上字串變成字串就會顯現出來了。顯現出來後可用他給的錯誤訊息去比對是怎樣的錯誤,通常不會更動,因此採用比對數字的方式去跳轉錯誤訊息。
login.php 檔:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>登入</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="warning">
<strong> 警告!有資安漏洞! </strong>
</header>
<main class="board">
<div>
<a class="board__btn" href="index.php">回留言板</a>
<a class="board__btn" href="register.php">註冊</a>
</div>
<h1 class="board__title">登入</h1>
<?php
if(!empty($_GET['errCode'])) {
$code = $_GET['errCode'];
$msg = 'Error';
if($code === '1') {
$msg = '錯誤:資料不齊全';
} else if ($code === '2') {
$msg = '錯誤:帳號或密碼輸入錯誤';
}
echo '<h2 class="error">' . $msg . '</h2>';
}
?>
<form class="board__new-comment-form"method="POST" action="handle_login.php">
<div class="board__nickname">
<span>帳號:</span>
<input type="text" name="username" />
</div>
<div class="board__nickname">
<span>密碼:</span>
<input type="password" name="password" />
</div>
<input class="board__submit-btn" type="submit" />
</form>
</main>
</body>
</html>
handle_login.php 檔:
<?php
require_once('conn.php');
if (
empty($_POST['username']) ||
empty($_POST['password'])
) {
header('Location: login.php?errCode=1');
die('資料不齊全');
}
$username = $_POST['username'];
$password = $_POST['password'];
$sql = sprintf(
"select * from users where username='%s' and password='%s'",
$username,
$password
);
$result = $conn->query($sql);
if (!$result) {
die($conn->error);
}
if ($result -> num_rows) {
echo '登入成功';
} else {
header("Location: login.php?errCode=2");
}
?>
index.php 檔:
<?php
require_once("conn.php");
$result = $conn -> query("SELECT * FROM comments order by id desc");
if(!$result) {
die('Error:' . $conn -> error);
}
$username = NULL;
if (!empty($_COOKIE['username'])) {
$username = $_COOKIE['username'];
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>留言板</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="warning">
<strong> 警告!有資安漏洞! </strong>
</header>
<main class="board">
<div>
<?php if (!$username) { ?>
<a class="board__btn" href="register.php">註冊</a>
<a class="board__btn" href="login.php">登入</a>
<?php } else { ?>
<a class="board__btn" href="logout.php">登出</a>
<?php } ?>
</div>
<h1 class="board__title">Comments</h1>
<?php
if(!empty($_GET['errCode'])) {
$code = $_GET['errCode'];
$msg = 'Error';
if ($code === '1') {
$msg = '錯誤:資料不齊全';
}
echo '<h2 class="error">' . $msg . '</h2>';
}
?>
<form class="board__new-comment-form"method="POST" action="handle_add_comment.php">
<div class="board__nickname">
<span>暱稱:</span>
<input type="text" name="nickname" />
</div>
<textarea name="content" rows="5"></textarea>
<input class="board__submit-btn"type="submit" />
</form>
<div class="board__hr"></div>
<section>
<?php
while($row = $result -> fetch_assoc()) {
?>
<div class="card">
<div class="card__avatar">
</div>
<div class="card__body">
<div class="card__info">
<span class="card__author">
<?php echo $row['nickname'];?>
</span>
<span class="card__time">
<?php echo $row['created_at'];?>
</span>
</div>
<p class="card__content"><?php echo $row['content']?></p>
</div>
</div>
<?php } ?>
</section>
</main>
</body>
</html>
handle_login.php 檔:
<?php
require_once('conn.php');
if (
empty($_POST['username']) ||
empty($_POST['password'])
) {
header('Location: login.php?errCode=1');
die('資料不齊全');
}
$username = $_POST['username'];
$password = $_POST['password'];
$sql = sprintf(
"select * from users where username='%s' and password='%s'",
$username,
$password
);
$result = $conn->query($sql);
if (!$result) {
die($conn->error);
}
if ($result -> num_rows) {
$expire = time() + 3600 * 24 * 30;
setcookie("username", $username, $expire);
header("Location: index.php");
} else {
header("Location: login.php?errCode=2");
}
?>
logout.php 檔
<?php setcookie("username", "", time() - 3600);
header("Location: index.php");
?>
index.php
<?php
require_once("conn.php");
$result = $conn -> query("SELECT * FROM comments order by id desc");
if(!$result) {
die('Error:' . $conn -> error);
}
$username = NULL;
if (!empty($_COOKIE['username'])) {
$username = $_COOKIE['username'];
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>留言板</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="warning">
<strong> 警告!有資安漏洞! </strong>
</header>
<main class="board">
<div>
<?php if (!$username) { ?>
<a class="board__btn" href="register.php">註冊</a>
<a class="board__btn" href="login.php">登入</a>
<?php } else { ?>
<a class="board__btn" href="logout.php">登出</a>
<?php } ?>
</div>
<h1 class="board__title">Comments</h1>
<?php
if(!empty($_GET['errCode'])) {
$code = $_GET['errCode'];
$msg = 'Error';
if ($code === '1') {
$msg = '錯誤:資料不齊全';
}
echo '<h2 class="error">' . $msg . '</h2>';
}
?>
<?php if ($username) { ?>
<form class="board__new-comment-form"method="POST" action="handle_add_comment.php">
<textarea name="content" rows="5"></textarea>
<input class="board__submit-btn"type="submit" />
</form>
<?php } else { ?>
<h3>請登入發布留言</h3>
<?php } ?>
<div class="board__hr"></div>
<section>
<?php
while($row = $result -> fetch_assoc()) {
?>
<div class="card">
<div class="card__avatar">
</div>
<div class="card__body">
<div class="card__info">
<span class="card__author">
<?php echo $row['nickname'];?>
</span>
<span class="card__time">
<?php echo $row['created_at'];?>
</span>
</div>
<p class="card__content"><?php echo $row['content']?></p>
</div>
</div>
<?php } ?>
</section>
</main>
</body>
</html>
handle_login.php
<?php
require_once('conn.php');
if (
empty($_POST['username']) ||
empty($_POST['password'])
) {
header('Location: login.php?errCode=1');
die('資料不齊全');
}
$username = $_POST['username'];
$password = $_POST['password'];
$sql = sprintf(
"select * from users where username='%s' and password='%s'",
$username,
$password
);
$result = $conn->query($sql);
if (!$result) {
die($conn->error);
}
if ($result -> num_rows) {
$expire = time() + 3600 * 24 * 30;
setcookie("username", $username, $expire);
header("Location: index.php");
} else {
header("Location: login.php?errCode=2");
}
?>
handle_add_comment.php
<?php
require_once('conn.php');
if (
empty($_POST['content'])
) {
header('Location: index.php?errCode=1');
die('資料不齊全');
}
$username = $_COOKIE['username'];
$user_sql = sprintf(
"select nickname from users where username='%s'",
$username
);
$user_result = $conn -> query($user_sql);
$row = $user_result -> fetch_assoc();
$nickname = $row['nickname'];
$content = $_POST['content'];
$sql = sprintf(
"insert into comments(nickname, content) values('%s', '%s')",
$nickname,
$content
);
$result = $conn->query($sql);
if (!$result) {
die($conn->error);
}
header("Location: index.php");
?>
client 端的資料可以更改,如果 server 端的資料能改就已經是被駭。
假設程式碼會被偷,如何維持資料安全性?
資料庫裡面有的名字才能改。
加入新增留言功能
如果錯誤顯示在某一行,不代表錯誤真的在該行,有可能是前面的錯誤導致影響後面的錯誤。
white-space & word-break 為前端非常常使用之兩個 CSS 語法,務必記得。
index.php 檔:
CSS 檔:
handle_add_comment.php 檔: