<form id="from1" name="form1" method="post" action="">
用户名 <input type="text" name="username"/>
<br>
<br>
<br>
内容:
<textarea name="content">
</textarea>
<input type="submit" name="submit" id="submit" value="提交">
</form>
<?php
$u = @$_POST['username'];
$c = @$_POST['content'];
echo $u;
echo $c;
<?php
$dbip='localhost';
$dbuser='root';
$dbpass='rooter';
$dbname='demo1';
$con=mysqli_connect($dbip,$dbuser,$dbpass,$dbname);
if (!$con) {
die("连接失败 " + mysqli_connect_error());
} else {
echo "OK!";
//
<?
echo "ok!"
$u = @$_POST['username'];
if(isset($u)) {
$c = @$_POST['content'];
$i = @$_SERVER['REMOTE_ADDR'];
$UA = @$_SERVER['HTTP_USER_AGENT'];
$sql = "insert into gbook(username,content,ipaddr,uagent) values('$u','$c','$i','$UA')";
echo $sql;
mysqli_query($con,$sql);}
?>
//错误 : 数据库语句必须以引号进行包裹,并且,字段名不能加引号,对应的值要加引号
<?php
if (mysqli_query($con,$sql)) {
echo "<script>alert('留言成功!');</script>";
$sql1 = "select * from gbook where username = '$u'";
$data = mysqli_query($con,$sql1);
while($row = mysqli_fetch_row($data)) {
printf("%s : %s" , $row[0],$row[1]);
echo "<br>";
}//修改版
echo "<script>alert('留言成功!');</script>";
$sql1 = "select * from gbook where username = '$u'";
$data = mysqli_query($con,$sql1);
while($row = mysqli_fetch_row($data)) {
echo '用户名: '. $row[0].'<br>' ;
echo '内容: ' . $row[1].'<br>' ;
echo '地址: ' . $row[2].'<br>' ;
echo 'UA头: ' . $row[3].'<br>' ;
echo '<hr>';
}
// 查询步骤:
1、创建sql语句 select * from gbook;
1、将sql语句带入数据库查询 : $data = mysqli_query($con,$sql1);
2、读取结果:
while($row = mysqli_fetch_row($data)) {
printf("%s : %s" , $row[0],$row[1]);
echo "<br>";
}
include '../config.php'; //记住一定要加引号
1、将查询语句照搬过去,然后添加删除按钮
$sql1 = "select * from gbook ";
$data = mysqli_query($con,$sql1);
while($row = mysqli_fetch_row($data)) {
echo '用户名: ' . $row[0] . '<br>';
echo '内容: ' . $row[1] . '<br>';
echo '地址: ' . $row[2] . '<br>';
echo 'UA头: ' . $row[3] . '<br>';
echo '<hr>';
}
2、需要编写数据库连接语句,但是为了不重复去写,使用包含语句
* 首先创建 config.php文件
<?php
$dbip = 'localhost';
$dbuser = 'root';
$dbpass = 'rooter';
$dbname = 'demo1';
$con = mysqli_connect($dbip, $dbuser, $dbpass, $dbname);
?>3、在 gbook-admin.php 中加入
include '../config.php'; //记住一定要加引号
4、在gbook.php中加入
include 'config.php' //具体加不加../ 可以将鼠标放于其上观察提示符
5、在管理员界面为记录添加删除按钮
echo "<a href='/admin/gbook-admin.php?del=$row[0]'>删除</a>";
echo '<hr>';
}
$delstr = @$_GET['del'];
$sql2 = "delete from gbook where username = '$delstr'";
if (mysqli_query($con,$sql2)) {
echo '<script>alert("删除成功")</script>';
}
//注意:这里的$delstr 一定要以单引号包裹,双引号包裹SQL语句即可,不然会出现将$delstr当作字符串的情况
1、插入函数
function add_gbook($con)
{
$u = @$_POST['username'];
if (isset($u)) {
$c = @$_POST['content'];
$i = @$_SERVER['REMOTE_ADDR'];
$UA = @$_SERVER['HTTP_USER_AGENT'];
$sql = "insert into gbook(username,content,ipaddr,uagent) values('$u','$c','$i','$UA')";
if (mysqli_query($con, $sql)) {
echo "<script>alert('留言成功!');</script>";
}
}
}
2、查询函数
function show_gbook($con)
{
$sql1 = "select * from gbook";
$data = mysqli_query($con, $sql1);
while ($row = mysqli_fetch_row($data)) {
echo '用户名: ' . $row[0] . '<br>';
echo '内容: ' . $row[1] . '<br>';
echo '地址: ' . $row[2] . '<br>';
echo 'UA头: ' . $row[3] . '<br>';
echo '<hr>';
}
}
<script src="/ueditor/ueditor.config.js">/*引入配置文件*/</script>
<script src="/ueditor/ueditor.all.js">/*引入资源文件*/</script>
<form id="from1" name="form1" method="post" action="">
用户名 <input type="text" name="username"/>
<br>
<br>
<br>
内容:
<textarea id="content" rows="10" cols="70" name="content" sytle="border:1px solid #E5E5E5;">
</textarea>
<script type="text/javascript">
UE.getEditor("content");
</script>
<br>
<br>
<br>
<br>
<input type="submit" name="submit" id="submit" value="提交">
</form>
1、使用 ChatGpt 生成登陆页面的样式
2、接受用户输入的账号密码
3、创建对应的用户密码数据库
4、连接数据库(使用包含语句 include)
5、判断账号密码的正确性
mysqli_num_rows 函数
跳转:'Location:index-c.php')
6、登录成功后跳转到index-c.php页面,但是现在index-c.php是可以直接访问的,所以进行设置
7、设置Cookie以及有效性
8、对于页面一直弹框(登录失败)进行条件提交方法的校验,使之不随意弹窗
if ($_SERVER['REQUEST_METHOD'] == "POST") {
//判断用户登录成功 也防止用户未登录就一直跳提示
$user = $_POST['username'];
$passwd = $_POST['password'];
$sql = "select * from admin where username='$user' and password = '$passwd'";
$data = mysqli_query($con,$sql);
if (mysqli_num_rows($data) > 0) {
$expire = time() + 60 * 60 * 24 * 30; // 设置失效时间为一个月 time()返回当前的时间戳
setCookie('username',$user,$expire,'/');
// username -- Cookie的键名,$user -- 值 $expire -- 持续时间 '/'在哪个页面可以进行访问
setCookie('password',$passwd,$expire,'/');
echo '<script>alert("登录成功!")</script>';
// header('Location: index-c.php');
exit();
} else {
// 判断用户登录失败
echo '<script>alert("登录失败!")</script>';
}
}
// 1.注意,数据库输入数据后一定保证点击确认箭头,否则会逻辑出问题
setcookie("字段",值,时间 , 存储在哪个目录)
mysqli_num_rows($data)
//当只有Cookie进行身份验证时,Cookie中是不存在PHPSESSID的1、编写来达到通过是否设置Cookie判断能否进入该页面的效果
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>后台首页</title>
</head>
<body>
<h1>后台首页</h1>
<p>欢迎您,<?php echo $_COOKIE['username']; ?>!</p>
<p><a href="logout-c.php">退出登录</a></p>
</body>
</html>
<?php
//阻止用户不经验证直接访问该页面,如果存在则返回登录页面
if ($_COOKIE['username']!= 'admin' and $_COOKIE['password'] != '123456') {
header('Location:admin-c.php');
}
?>
1、当跳转到登出界面时,删除用户的Cookie(置空)
<?php
setcookie('username','',time() - 3600,'/');
setcookie('password','',time(),'/');
header('Location:admin-c.php');
exit();
?>1、从登录页面输入正确账号密码,会通过Cookie的认证跳转index页面,那么只要知道Cookie,并伪造,就可以登录别人的用户
补充:既然session比Cookie安全为什么不都使用session?
因为session是存储在服务器上的,当用户数量多,那么占据的负载就多,会影响服务器的响应速度
1、验证sesssion是否正确,并且提前要开启session会话
补充:PHPSESSID 是存储session文件的名字,而不是session的内容
session如果想要替换,替换的不是内容而是上方的文件名称(编号)
<?php
session_start();
if ($_SESSION['username'] != 'admin' && $_SESSION['password'] != '123456') {
header('Location : admin-s.php');
exit();
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>后台首页</title>
</head>
<body>
<h1>后台首页</h1>
<p>欢迎您,<?php echo $_SESSION['username']; ?>!</p>
<p><a href="logout-s.php">退出登录</a></p>
</body>
</html>
// 注意:如果想要取session中的字段,那么session_start()必须放在第一位,就是HTML也不可以例外
1、首先还是接收用户输入,然后验证是否存在用户,存在后进行下一步处理
2、编写session验证 (session存储路径在php.ini中寻找session.save_path即可知道)
<?php
include '../config.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$user = $_POST['username'];
$passwd = $_POST['password'];
$sql = "select * from admin where username = '$user' and password = '$passwd'";
$data = mysqli_query($con,$sql);
if (mysqli_num_rows($data) > 0) {
session_start();
$_SESSION['username'] = $user;
$_SESSION['password'] = $passwd;
echo '<script>alert("登录成功!")</script>';
header('Location:index-s.php');
exit();
}else {
echo '<script>alert("登录失败!")</script>';
}
}
?>
// 如果设置了session,那么Cookie中会出现
PHPSESSID mbap7nednjo4nm5jf0n7i3n 字段 后面为存储session文件的文件名
1、用户一旦点击退出登录,那么跳转该页面将session进行销毁,然后返回admin页面进行重新登录
<?php
//开始会话
session_start();
//清除session 变量,并销毁会话
session_unset();
//清空当前session会话中的所有数据
session_destroy();
//销毁当前会话
header('Location: admin-s.php');
exit();
?>//主要是 session_unset(); 和 session_destroy()这两个函数
判断Cookie和session主要看时间,比如过半个小时需要重新登录,那么一定是session
<?php
// 生成Token并将其存储在Session中
session_start();
//1.因为是用的session维持会话,token已经绑定到下面的表单了
//2.token,生成之后直接存到session里,主要是方便重置token,
//每次token随表单提交后都需要重置以保持token的唯一性。
$_SESSION['token'] = bin2hex(random_bytes(16));
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>后台登录</title>
<style>
body {
background-color: #f1f1f1;
}
.login {
width: 400px;
margin: 100px auto;
background-color: #fff;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0,0,0,0.3);
padding: 30px;
}
.login h2 {
text-align: center;
font-size: 2em;
margin-bottom: 30px;
}
.login label {
display: block;
margin-bottom: 20px;
font-size: 1.2em;
}
.login input[type="text"], .login input[type="password"] {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 1.2em;
margin-bottom: 20px;
}
.login input[type="submit"] {
background-color: #2ecc71;
color: #fff;
border: none;
padding: 10px 20px;
border-radius: 5px;
font-size: 1.2em;
cursor: pointer;
}
.login input[type="submit"]:hover {
background-color: #27ae60;
}
</style>
</head>
<body>
<div class="login">
<h2>后台登录</h2>
<form action="token_check.php" method="post">
<input type="hidden" name="token" value="<?php echo $_SESSION['token'] ; ?>">
<label for="username">用户名:</label>
<input type="text" name="username" id="username" required>
<label for="password">密码:</label>
<input type="password" name="password" id="password" required>
<input type="submit" value="登录">
</form>
</div>
</body>
</html>
<?php
session_start();
$token = $_POST['token'] ?? '';
if ($token !== $_SESSION['token']) {
header('HTTP/1.1 403 Forbidden');
$_SESSION['token'] = bin2hex(random_bytes(16));
//重置 Token(防止重复尝试
echo 'Access denied';
exit;
}else {
$_SESSION['token'] = bin2hex(random_bytes(16));
//一旦验证成功立马重置token防止多次爆破利用
if($_POST['username']=='admin' && $_POST['password']=='123456'){
echo '登录成功!';
echo '你是管理员可以访问文件管理页面!';
}else{
echo '登录失败!';
}
}补充:第一次token出现问题原因是插件的自动访问,它会在用户访问登录页面的时候重新访问,那么就相当于将session重置了,而用户提交的是旧token当然即使输入正确的账号密码都是无法登录的了
还有,使用127.0.0.1建设的网站抓包工具抓不到
使用内网IP进行替换 比如:192.168.100.200/gbook.php
1、编写文件上传页面
2、读取上传文件信息
3、将文件从临时文件夹移动到目录
补充:这里被移到的目录必须有写入权限
//html只是写了一个文件上传页面,可以自己编写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传页面</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f2f2f2;
padding: 20px;
}
h1 {
text-align: center;
margin-top: 50px;
}
form {
background-color: #fff;
border-radius: 10px;
padding: 20px;
margin-top: 30px;
max-width: 600px;
margin: 0 auto;
}
input[type="file"] {
margin-top: 20px;
margin-bottom: 20px;
}
button {
background-color: #4CAF50;
color: #fff;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background-color: #3e8e41;
}
</style>
</head>
<body>
<h1>文件上传</h1>
<form action="upload.php" method="POST" enctype="multipart/form-data">
<label for="file">选择文件:</label>
<br>
<input type="file" id="file" name="f">
<br>
<button type="submit">上传文件</button>
</form>
</body>
</html>
<?php
//显示文件信息
$name = $_FILES['f']['name'];
$type = $_FILES['f']['type'];
$size=$_FILES['f']['size'];
$tmp_name = $_FILES['f']['tmp_name'];
$error = $_FILES['f']['error'];
//这里的第一个括号内根据 (<input type="file" id="file" name="f">)中的name值来填
//第二个括号内的键值是固定的含义,直接英文翻译即可
echo $name.'<br>';
echo $type.'<br>';
echo $size.'<br>';
echo $tmp_name.'<br>';
echo $error.'<br>';
1、黑名单过滤
//上传文件后缀过滤,黑名单机制
$black_ext = array('php','asp','jsp','aspx');
$fenge = explode('.',$name);
$exts = end($fenge);
//end()函数功能:取数组中最后一个元素也就是后缀
if (in_array($exts,$black_ext)) {
echo '非法后缀文件'.$exts;
} else{
move_uploaded_file($tmp_name,'D:/phpstudy_pro/WWW/editor/upload/file/'.$name);
echo '<script>alert("上传成功!")</script>';
}
//注意,后面的目录中如果为文件夹一定要加’/‘,它是文件移动类似于剪切,必须有具体的文件名
结果在图库里面去找 2、白名单过滤
//白名单过滤
$allow_ext = array('jpg','png','gif','jpeg');
$fenge = explode('.',$name);
$exts = end($fenge);
if (!in_array($exts,$allow_ext)) {
echo '非法后缀文件'.$exts;
} else {
move_uploaded_file($tmp_name,'D:/phpstudy_pro/WWW/editor/upload/file/'.$name);
echo '<script>alert("上传成功")</script>';
}
3、MIME类型过滤
//MIME文件类型过滤
$allow_type = array('image/png','image/jpg','image/jpeg','image/gif');
if (!in_array($type,$allow_type)) {
echo '非法MIME类型'.'<br>'.$type;
}else {
move_uploaded_file($tmp_name,'D:/phpstudy_pro/WWW/editor/upload/file/'.$name);
echo '<script>alert("上传成功")</script>';
}
?>
// '??'这是 PHP 7 及以上版本新增的运算符,作用是:
//如果左侧的变量存在且不为 null,则返回左侧的值;
//否则返回右侧的默认值。
//1、打开目录,读取文件列表 opendir
//2、循环读取文件列表 while readdir
//3、判断是文件还是文件夹
//4、php.ini中设置 openbasedir = ’目录‘ 就会限制只能访问该目录下的文件夹和文件,防止目录遍历(记住要将前面的分号去掉)
<!-- 调用 PHP 函数生成动态列表 -->
<?php
// 先补全 PHP 目录处理代码(确保 $dir 和 filelist 函数已定义)
$dir = $_GET['path'] ?? './';
$dir = rtrim($dir, '/') . '/';
function filelist($dir) {
if ($dh = opendir($dir)) {
while(($file = readdir($dh)) !== false) {
if ($file == '.' || $file == '..') continue;
$fullPath = $dir . $file;
if (is_dir($fullPath)) {
echo "<li><i class='fa fa-folder'></i> <a href='?path=" . urlencode($fullPath) . "'>" . $file . '</a></li>';
} else {
echo '<li><i class="fa fa-file"></i> <a href="' . $fullPath . '">' . $file . '</a></li>';
}
}
closedir($dh);
} else {
echo "<li>无法打开目录:$dir</li>";
}
}
// 调用函数生成列表
filelist($dir);
?>
1、php.ini中设置 openbasedir = ’‘ 如果不设置,那么就可以一直回溯到C盘/根目录
2、 考虑 -- 只要文件存放目录存在于服务器,就可以尝试取遍历,?path=admin