欢迎光临
我们一直在努力

XSS渗透 Session

一、为什么需要 Session?(Cookie 的两个问题)

Cookie 虽然解决了 HTTP 无状态的问题,但带来了新问题:

  • 存储空间浪费:访问网站越多,浏览器本机保存的 Cookie 越多(每个网站可能下发几十个),占用磁盘/内存。
  • 通信效率降低:每次请求都要携带所有 Cookie(可能几百字节甚至几 KB),增加 HTTP 传输开销,拖慢速度。
  • 核心思路:将大量的键值对信息从客户端转移到服务端存储,客户端只保存一个唯一的标识(类似医院的“诊疗卡号”)。


    二、Session 是什么?

    • Session(会话):服务端为每个客户端开辟的一块存储空间,用于保存该客户端的键值对数据(如用户ID、登录状态、权限等)。
    • Session ID:服务端生成的一个唯一标识,通过 Cookie 下发给客户端。客户端后续请求只需携带这个 ID,服务端根据 ID 找到对应的 Session 数据。

    关键点:

    • Session 不是替代 Cookie,而是基于 Cookie 工作。
    • Cookie 中保存的内容被简化为一个 Session ID(如 PHPSESSID=abc123)。
    • 真正的用户数据保存在服务端(文件、内存、Redis 等)。

    三、Session 的工作流程(四步)

    步骤 方向 动作 说明
    1. 创建会话 客户端第一次访问 服务端调用

    session_start()

    生成 Session ID,通过

    Set-Cookie

    下发

    此时 Session 存储区为空
    2. 写入数据 服务端

    $_SESSION

    中存入键值对(如

    $_SESSION['username']='admin'

    数据保存在服务端
    3. 验证会话 客户端再次访问 浏览器自动携带 Cookie 中的 Session ID,服务端根据 ID 找到 Session 数据 判断是否已登录、有无权限
    4. 销毁会话 用户注销 服务端清空

    $_SESSION

    并调用

    session_destroy()

    ,同时删除相关持久 Cookie

    彻底结束会话


    四、Session 与 Cookie 的对比

    对比项 Cookie Session
    数据存储位置 客户端(浏览器) 服务端(文件/内存/Redis)
    每次请求传输的内容 所有 Cookie 的 name=value(可能几十个) 仅一个 Session ID(如

    PHPSESSID=xxx

    存储大小限制 每个域名约 50 个,每个 4KB 受服务端资源限制,可存大量数据
    安全性 明文存储,可被篡改/查看(HttpOnly 可部分防御) 数据不暴露给客户端,更安全
    生命周期 可设置过期时间,也可会话级 通常随会话结束或主动销毁
    依赖关系 独立存在 依赖 Cookie 传递 Session ID(也可通过 URL 重写,但不常用)

    五、Session 的存储位置(配置相关)

    • 默认(PHP):以文件形式保存在服务器磁盘上(如 /tmp 或 PHP 配置指定的目录)。每个 Session 对应一个文件,文件名包含 Session ID。 文件内容为序列化后的 $_SESSION 数据,例如:username|s:5:"admin";islogin|i:1;
    • 可配置存储方式:
      • 文件(默认)
      • 内存缓存(如 Memcached)
      • 数据库(如 MySQL)
      • Redis(常用,支持分布式)

    示例:

    修改 PHP 配置 session.save_handler = redis 和 session.save_path = "tcp://127.0.0.1:6379" 可让 Session 存入 Redis。


    六、Session 的典型应用场景

  • 用户登录状态保持
    • 登录成功后,将 user_id 和 is_login 存入 $_SESSION。
    • 后续请求只需校验 Session 中是否有 is_login=true,无需重复查询数据库。
  • 购物车数据
    • 未登录时购物车数据可存 Cookie,登录后合并到 Session 中。
  • 验证码/短信验证码存储
    • 生成验证码时存入 Session,用户提交时对比,防止篡改。
  • 权限控制
    • 用户登录后,将角色、权限列表存入 Session,避免每次请求都查数据库。

    七、“记住我”(7天免登录)的实现方式

    Session 本身默认过期时间较短(如 1440 秒)。要实现“7天内自动登录”,需要额外设置持久 Cookie,并配合 Session 使用:

    // 登录时勾选“记住我”
    if($_POST['remember']=="yes") {
    setcookie("admin", $username, time()+7*24*60*60);
    setcookie("code", md5($username.md5($password)), time()+7*24*60*60);
    }

    • 真正登录凭证存在 $_SESSION 中($_SESSION['username'] 和 $_SESSION['islogin'])。
    • 持久 Cookie(admin 和 code)用于下次访问时自动重建 Session。
    • 典型自动登录流程:用户再次访问时,先检查 Session 是否为空;若为空则校验持久 Cookie,校验通过后重新 session_start() 并写入 $_SESSION。

    八、注销时如何完整清除会话

    正确的注销代码应做四件事(参考 logout.php):

    session_start(); // 1. 恢复当前会话
    $username = $_SESSION['username']; // 2. 记录用户名用于提示
    $_SESSION = array(); // 3. 清空 $_SESSION 数组
    session_destroy(); // 4. 删除服务端的 Session 文件
    setcookie("admin",'',time()-1); // 5. 删除“记住我”的持久 Cookie
    setcookie("code",'',time()-1); // 6. 同上

    注意:

    • 这里没有删除 PHPSESSID 这个 Cookie(浏览器还会保留一个过期的 Session ID),但服务端 Session 已销毁,该 ID 无效。如需彻底删除客户端 Session ID,可执行

      setcookie(session_name(), '', time()-3600, '/')。

    • 持久 Cookie(如 admin、code)必须手动删除,否则下次访问时可能被错误地用于自动登录。

    九、完整登录流程时序

    步骤 文件 动作 关键代码
    1. 用户访问登录页 login.html 显示表单,包含用户名、密码、“记住我”复选框

    2. 提交表单 login.php session_start()

    开启会话

    session_start();
    3. 验证账号密码 login.php 硬编码验证

    admin/123456

    if(($username=='admin')&&($password=='123456'))
    4. 写入 Session login.php 保存用户名和登录状态 $_SESSION['username']=$username; $_SESSION['islogin']=1;
    5. 设置持久 Cookie login.php 如果勾选“记住我”,设置 7 天有效 Cookie setcookie("admin",$username,time()+7*24*60*60);
    6. 跳转用户中心 login.php header('refresh:3;url=index.php');
    7. 验证登录状态 index.php 检查

    $_SESSION['username']

    是否存在

    if(isset($_SESSION['username']))
    8. 显示个人中心 index.php 显示欢迎信息和注销链接 echo $_SESSION['username'].":你好…";
    9. 注销 logout.php 清除 Session 和持久 Cookie session_destroy(); setcookie("admin",'',time()-1);

    十、注意事项

    • session_start() 必须在任何输出之前调用(包括 header() 和 echo),否则会报错。
    • 不同浏览器的 Session 互不影响,因为 Cookie 不共享。同一浏览器的不同标签页/窗口共享 Session。
    • 分布式环境需将 Session 集中存储(如 Redis),不能使用默认的文件存储。
    • Session 不是万能的:对于纯 API 服务(无浏览器环境),更多使用 Token(如 JWT)。

    十一、一句话总结

    Cookie 存在客户端,用来保存数据(如 Session ID)。

    Session 存在服务端,用来保存真正的用户数据。

    两者配合:服务端通过 Cookie 下发一个 Session ID,客户端下次请求带上它,服务端就能找到对应的 Session 数据。


    这份笔记已经包含了原版的所有内容,并融入了你提供的代码示例和补充说明。如果你觉得还有需要微调的地方(比如去掉某些细节或增加流程图文字),请告诉我。

    下面附上参考代码

    login.php

    <?php
    header("Content-Type:text/html;charset=utf-8");
    // 开启会话,产生sessionid
    session_start();
    if(isset($_POST['login']))
    {
    $username = trim($_POST['username']);
    $password = trim($_POST['password']);
    if(($username=='')||($password==''))
    {
    header('refresh:3;url=login.html');
    echo "用户名或密码不能为空,3秒后跳转到登录页面";
    exit;
    }
    // 用户名和密码没有查表,直接写死,只是个参考
    else if(($username!='admin')||($password!='123456'))
    {
    //用户名或密码错误
    header('refresh:3;url=login.html');
    echo "用户名或密码错误,3秒后跳转到登录页面";
    exit;
    }
    // 没有查表,直接写死
    else if(($username=='admin')&&($password=='123456'))
    {
    //登录成功将信息保存到session中
    $_SESSION['username']=$username;
    $_SESSION['islogin']=1;
    //如果勾选7天内自动保存,则将其保存到cookie
    if($_POST['remember']=="yes")
    {
    setcookie("admin",$username,time()+7*24*60*60);
    setcookie("code",md5($username.md5($password)),time()+7*24*60*60);
    }
    else
    {
    setcookie("admin",'',time()-1);
    setcookie("code",'',time()-1);
    }
    //跳转到用户首页
    header('refresh:3;url=index.php');
    }
    }
    ?>

    index.php

    <?php
    header("Content-Type:text/html;charset=utf-8");
    session_start();
    // session中有这个用户名,代表已经登录
    if(isset($_SESSION['username']))
    {
    echo $_SESSION['username'].":你好,欢迎进入个人中心!<br/>";
    echo "<a href='logout.php'>注销</a>";
    } else {
    // 没有这个用户名的session值
    echo "你还未登录,请<a href='login.html'>登录</a>";
    }
    ?>

    logout.php

    <?php
    header("Content-Type:text/html;charset=utf-8");
    session_start();
    //清除session
    $username=$_SESSION['username'];
    $_SESSION=array();
    session_destroy();
    //清除cookie
    setcookie("username",'',time()-1);
    setcookie("code",'',time()-1);
    echo "拜拜, $username, 欢迎下次光临";
    echo "重新<a href='login.html'>登录</a>";
    ?>

    赞(0)
    未经允许不得转载:171主机测评 » XSS渗透 Session
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址