Day23 -php开发02 --后台模块+ 三种验证方式(cookie + session +token)

一、cookie 与 session的区分

1)cookie

特点:存储小型文件(例如:用户名和密码);将登录用户的敏感信息以加密字符串形式存储在浏览器上;存储在浏览器上;如果不清除浏览器的cookie记录,那么记录会一直存在,相比安全性一般

2)session

特点:存储较大型文件(例如:购物车、登录状态);将登录用户的敏感信息以文件形式存储在服务器上;如果用户关闭了当前页面,会自动删除session文件,安全性高,相对应的维护成本也提高;

3)如何识别一个web是cookie还是session?

法1:目标规模大,一般是session;否则为cookie

**法2**:登陆后不动,一段时间(10min/30min/1h)后来看结果,需要重新登录的就是session

法3:关闭浏览器,还能登录是cookie;否则是session

二、token

唯一性

一个数据包对应唯一的token值,否则会被服务器认定为垃圾包,直接丢弃不予通过。

三、实际开发中不同验证方式的运用

前置要求:小皮开启web + navicat连接好数据库 +新建一张admin表

【1】Cookie

文件要求:创建好三个文件,分别负责登录、登出、登录成功后的首页

00x1 前端html制作

扔给gpt,指令:html写一个后台登陆漂亮的页面

00x2  登录(admin-c.php)逻辑考量

00x3 按照逻辑进行登录验证开发
// 1.接收输入的账号和密码
$user = $_POST['username'];
$pass = $_POST['password'];

// 2.判断账号密码正确性
$sql = "select * from admin where username='$user' and password='$pass';";
    // 判断mysql查询结果
$data = mysqli_query($con,$sql);
if ($_SERVER["REQUEST_METHOD"] == "POST"){  # 防止没有提交账密的情况下提示登录失败
    if (mysqli_num_rows($data)>0){    # 利用返回行数函数来判断:如果用户输入的账号密码在mysql表中有记录,那么就一定返回>0行
        # echo 'ok';                  #  那么就可以确认账号密码是正确的
        // 3.设置cookie并进行保存
        $expire = time() + 60 * 60 * 24 * 30;  # time()截取当前时间;整行意为一个月过期
        setcookie('username',$user,$expire,'/');
        setcookie('password',$pass,$expire,'/');
        // 4.跳转至成功登录的页面
        # echo "<script>alert('登录成功!')</script>";  #  给一个js弹窗登录成功
        header('Location:admin-c.php');  #  确认账密正确,利用header跳转首页
    }else{
        echo "<script>alert('登录失败')</script>";  # 如果mysql表中没有这条记录,js弹窗给一个登陆失败的tips
    }
}

验证一下:成功跳转!cookie也在。

补充:

我们刚刚跳转成功,但是用户可以直接访问index.php地址,绕过登录,所以我们进一步对index做代码限制,防止绕过登录。

00x4 相对应对登陆后首页(index-c.php)逻辑考量 & 开发

前端逻辑:

完善:防止他直接访问站点绕过登录,那么就是再加一个验证,验证cookie中接收到了username以及password

【如果缺一或均无  ---> 跳转到admin-c.php重新登陆】

【如果有  ---> 无事发生 继续留在index.php中】

<?php
// 登录成功后的首页
include "../config.php";


// cookie中来判断是否登录
if (!isset($_COOKIE['username']) || !isset($_COOKIE['password'])) {
    header('Location: admin-c.php'); // 如果username/password中其一没有 --> 未登录 --> 跳转登录页
    exit();
}

?>

00x5 对登出页面(logout-c.php)进行逻辑考量 & 开发

思路就是:将cookie清除,并跳转到登录页面

<?php
//登出页面

// 将cookie值清空,时效为去除当前时间一个小时前的;
setcookie('username', '', time() - 3600, '/');
setcookie('password', '', time() - 3600, '/');
// 跳转到登录页面
header('Location: admin-c.php');
exit;

*** 攻击手法 ***

可以进行测试,输入错误的用户名/密码,然后给cookie中加上username & password

直接路径访问index-c.php

发现成功了,也就意为着cookie是可以被提取的,从而拿到敏感信息被拿到。

所以就引入一个比cookie更安全的验证方式,session验证。

【2】Session验证

00x1 前端html

继续复用漂亮的前端页面代码

00x2 登录界面admin-s.php的逻辑考虑
<?php
include "../config.php";

// 登陆文件采取session验证

//1、接收输入账号密码
$user = @$_POST['username'];  //加@防止瞎报错
$pass = @$_POST['password'];

// 相对应的去mysql查询记录
$sql = "select * from admin where username = '$user' and password = '$pass';";
$data = mysqli_query($con,$sql);

// 第一层if防止未提交数据弹窗登陆失败
// 第二层if是确认用户名和密码正确,且执行生成session
if ($_SERVER["REQUEST_METHOD"]=="POST"){
    if (mysqli_num_rows($data) > 0){
        session_start();
        $_SESSION['username'] = $user;
        $_SESSION['password'] = $pass;
        header('Location:index-s.php'); // 确认后跳转首页
    }else{
        echo "<script>alert('登录失败!')</script>";
    }
}

00x3 查看session文件

去php路径下的ini文件中,搜索session.save_path 

重启一下小皮 【web服务(apache /nigix)】

然后正确账密登录,去刚刚session存储路径发现了session文件

 

00x4 index首页逻辑

还是利用index-c.php的优雅前端页面,我们拿来用,只不过是提取session的值

<!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_start(),且要在html上面【因为_session全局变量,需要先启动】

<?php
session_start();
include "../config.php";

if (!isset($_SESSION['username']) || !isset($_SESSION['password'])) {
    header('Location: admin-s.php'); // 如果username/password中其一没有 --> 未登录 --> 跳转登录页
    exit();
}

?>

测试一下功能,成功。

00x5 session特性验证

就是对应唯一的session文件,假如我在谷歌浏览器登入成功,然后我拿url地址去egde浏览器,会成功绕过吗?答案是不成功,因为两次访问得到的是两个不同的session文件,这就是为什么session相比cookie要更加安全。

谷歌先登入  -->复制url

拿url粘贴到egde,看结果

未成功,还是登入界面

原因:

谷歌的session文件:

edge的session文件:

说明完全是两个session文件,完全无关。

00x6 登出逻辑 

要先清除一下session变量,并销毁,利用的是

session_unset();
session_destroy();

<?php
// 跳转到登录页面

// 开始会话
session_start();

// 清除 SESSION 变量,并销毁会话
session_unset();
session_destroy();

// 重定向到登录页面
header('Location: admin-s.php');
exit;
?>
*** 攻击手法 ***

1、先拿到可以登录的session值(edge)

2、session的替换

在edge的页面未关闭的情况下,将edge的session值替换给谷歌浏览器

3、以许可session去访问index-s.php

【3】token

原理:前面得知session存储在服务器中;所以原理是:服务器按照某种加密方式,出一串密文然后与session绑定成为session-token,我们提交表单的时候,带着这串密文(session-token)一起,以表单形式post到检查的地方,到了负责检查的地方,确认个人信息在库,同时确认我们提交的密文(post-token)与一开始他加密(session-token)给我们的是一样的,那么就给予通过。

以用户角度而言:用户压根不知道有token的存在,session与token绑定以后,成为session-token,然后被隐式的以表单形式传递给check检查的地方,但是检查的地方是按照post来接收这串密文(post-session),最终与session-token来判断,由于一样 自然通过。

00x1 生成密文的文件token.php的开发逻辑

1)前端

还是借用美观的后台页面

2)先生成随机密文,再与session绑定,这里为了后续做csrf等渗透测试,与cookie也做绑定

<?php
session_start();

// 生成随机的cookie
$token = bin2hex(random_bytes(16));

// 将token绑定到session中
$_SESSION['token'] = $token ;

// 将token绑定到cookie中
setcookie('token',$token,time()+3600,'/');

?>

3) 生成密文以后,前端的表单中加上传向的位置(token_check.php)和隐式传递的session-token(以post方式拿到,所以是post-token)

00x2 检查密文对应的文件token_check.php的开发逻辑

验证token是否一致  ----> 不一致   --->  进不去

                                 ----> 一致      --->  作废验证过的token。进一步去验证用户信息

<?php
session_start();
include "../config.php";

$user = @$_POST['username'];  //加@防止瞎报错
$pass = @$_POST['password'];

$token = $_POST['token'] ?? ''; // ??空合并运算符 --> 若有值赋值,若为空 赋空给变量token

if ($token !== $_SESSION['token']) {
    // token不匹配,禁止访问
    header('HTTP/1.1 403 Forbidden');
    $_SESSION['token'] = bin2hex(random_bytes(16));
    echo 'Access denied';
    exit;
}else{
    // 重新生成新token,旧的作废
    $_SESSION['token'] = bin2hex(random_bytes(16));
    // 进一步验证用户信息
    if($_POST['username']== $user && $_POST['password']== $pass ){
        echo '登录成功!';
        echo '你是管理员可以访问文件管理页面!';
    }else{
        echo '登录失败!';
    }
}

***验证唯一性效果***

00x1 bp抓包

故意输错密码,抓个包

00x2 发送到重放器尝试进行爆破

00x3 结果及原因分析

结果是尽管修改成正确的密码(或者给密码挂上一个字典,进行爆破),还是无法成功进入后台

原因:是因为我们第一次输错密码的时候,生成了一个session与token绑定,然后我们再次修改密码进行发包,这个时候旧的session-token就失效了,但是我们作为攻击者角度,是拿不到新的session-token进行提交的,所以自然访问也就失败了,这就是csrf-token防御的优秀之处,即使hacker拿到了敏感信息,但是拿不到session也就无法进入后台。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值