
目录一.Cookie1.原理2.代码实现1admin-c.php2Index-c.php3logout-c.php3.交作业二.Session1.原理2.代码实现1admin-s.php2index-s.php3logout-s.php3.交作业三.token1.原理3.代码实现1token.php2Token_check3.作业编辑在前一天的基础上实现后台登录cookie、session和token的身份验证。表单是让deepseek生成的简单页面。B站免费课程链接www.bilibili.com/video/BV12om2YTEgW/?spm_id_from333.788.videopod.episodesvd_source7d8464f1ea919ffdc1761c211c6d1c4ep24一.Cookie1.原理想象浏览器是一个每天都要去“网站大厦”办事的访客服务器就是大厦前台。第一次你来的时候报上账号密码前台核对无误后不会把你的身份证复印件贴在你脸上而是递给你一张写着随机编号的寄存牌——这张寄存牌就是 Cookie。浏览器会乖乖把它收进口袋。以后你每次再去这栋大厦还没等你开口浏览器就自动把寄存牌掏出来递给前台“喏这是我的牌。”前台拿着编号去后台柜子里一查就知道你是几号会员、有没有过期、是不是已经退房。牌子上没有你的密码只有一串谁也猜不到的编号就算你偷偷把编号改了后台查不到对应记录照样不认你。退出登录时前台要么把这张牌作废要么让浏览器直接把牌扔掉。所以Cookie 的工作机制就像一张“会自动出示的临时通行证”服务器发牌浏览器存牌每次访问同一网站时自动亮牌服务器凭牌去后台核对身份再决定放不放行。Cookie是保存在浏览器只要访问的cookie正确就能通过校验。常常会有钓鱼来做cookie劫持点击不知名链接就自动访问敏感站点然后把站点的cookie发给黑客。从而达到用受害者身份登录网站进行非法操作的目的。2.代码实现分为登录页面admin-c.php,登录成功后的后台页面index-c.php和退出登录logout-c.php。1admin-c.php!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title后台登录/title style * { box-sizing: border-box; } body { margin: 0; min-height: 100vh; background: #f0f2f5; font-family: -apple-system, Segoe UI, Microsoft YaHei, sans-serif; } .login-box { /* 关键脱离文档流相对视口居中 */ position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 10; width: 100%; max-width: 360px; padding: 32px 28px; background: #fff; border-radius: 10px; box-shadow: 0 4px 20px rgba(0, 0, 0, .08); } .login-box h1 { margin: 0 0 24px; font-size: 20px; text-align: center; color: #333; } .form-item { margin-bottom: 18px; } .form-item label { display: block; margin-bottom: 6px; font-size: 14px; color: #555; } .form-item input { width: 100%; height: 40px; padding: 0 12px; font-size: 14px; border: 1px solid #dcdfe6; border-radius: 6px; outline: none; transition: border-color .2s; } .form-item input:focus { border-color: #409eff; } .btn { width: 100%; height: 42px; margin-top: 8px; font-size: 15px; color: #fff; background: #409eff; border: none; border-radius: 6px; cursor: pointer; transition: background .2s; } .btn:hover { background: #66b1ff; } /style /head body div classlogin-box h1后台管理系统/h1 !-- 表单POST 提交 -- form action methodpost autocompleteoff div classform-item label forusername账号/label input typetext idusername nameusername placeholder请输入账号 required /div div classform-item label forpassword密码/label input typepassword idpassword namepassword placeholder请输入密码 required /div button typesubmit classbtn登 录/button /form /div /body /html ?php include ../config.php; //登录文件 /* cookie验证流程 1、接收输入的账号密码 2、判断账号密码正确性 3、正确后生成的cookie进行保存 3.1错误的账号密码进行提示 4、跳转至成功登录的页面 */ //1、接收输入的账号密码 $user$_POST[username]; $pass$_POST[password]; //2、判断账号密码正确性 //连接数据库 进行数据库查询将数据进行对比 $sqlselect * from admin where username$user and password$pass;; $datamysqli_query($con,$sql); //查询数据传给变量$data if($_SERVER[REQUEST_METHOD]POST){ if(mysqli_num_rows($data)0){ //mysqli_num_row函数是用来读取数据集有多少行如果通过sql语句在数据库查询到有这个用户和相应的密码记录那数据集就不会为0。则判断用户登录成功,继续往下执行。 $expire time() 60 * 60 * 24 * 30; // 单位为秒一个月后过期 setcookie(username, $user, $expire, /);//把用户名写入cookie setcookie(password, $pass, $expire, /);//把密码写入cookie echo scriptalert(登录成功)/script; header(Location: index-c.php);//跳转到index-c.php的页面也就是登录成功的页面 exit(); }else{ //判断用户登录失败 echo scriptalert(登录失败)/script; } }2Index-c.php!--cookie校验防止没有登陆直接未授权访问该页面-- ?php if($_COOKIE[username]!admin and $_COOKIE[password]!123456){ //获取cookie中的username和password字段是否不等于admin和123456不等于则继续往下执行 header(Location: admin-c.php); //跳转到登陆页面进行身份校验。 } ? //登录首页页面 !DOCTYPE html html head meta charsetutf-8 title后台首页/title /head body h1后台首页/h1 p欢迎您?php echo $_COOKIE[username]; ?/p pa hreflogout-c.php退出登录/a/p /body /html3logout-c.php?php setcookie(username, , time() - 3600, /);//setcookie的第三个参数是过期时间当前时间减去3600已经是过期了减去1也可以都是已经过去时间失效了。 setcookie(password, , time() - 3600, /); // 跳转到登录页面 header(Location: admin-c.php); exit; ?3.交作业登录页面后台首页浏览器中存储的cookie内容二.Session1.原理把服务器想象成一座管理严格的游乐园登录页 admin-s.php 就是大门口。你递上账号密码验票员去数据库名单里核对一旦确认他并不让你把身份证贴在脑门上到处跑而是给你手腕套一个独一无二的手环——这就是 Session ID浏览器通常把它存在 Cookie 里。与此同时游乐园后台的档案柜里多了一份你的临时档案你是谁、是不是 admin、密码对不对、能进哪些地方这些就是 $_SESSION。之后你每走到一个页面比如 index-s.php门口保安不看你别的东西只看手环编号然后回档案柜里一查编号有没有、档案在不在、身份对不对。对上了放行对不上、手环过期、档案被销毁或者你从 logout-s.php 出口剪掉手环就一律被请回大门口重新登录。所以 Session 验证的精髓是客户端拿的只是一张“临时通行证编号”真正说了算的身份档案始终锁在服务器自己手里。因为真正的凭据内容在服务器端不像cookie直接放在浏览器所以比前面的cookie安全一点存储到服务器但是增加服务器存储session的成本。流程图总体架构图登录、校验、退出时序图2.代码实现1admin-s.php!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title后台登录/title style * { box-sizing: border-box; } body { margin: 0; min-height: 100vh; background: #f0f2f5; font-family: -apple-system, Segoe UI, Microsoft YaHei, sans-serif; } .login-box { /* 关键脱离文档流相对视口居中 */ position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 10; width: 100%; max-width: 360px; padding: 32px 28px; background: #fff; border-radius: 10px; box-shadow: 0 4px 20px rgba(0, 0, 0, .08); } .login-box h1 { margin: 0 0 24px; font-size: 20px; text-align: center; color: #333; } .form-item { margin-bottom: 18px; } .form-item label { display: block; margin-bottom: 6px; font-size: 14px; color: #555; } .form-item input { width: 100%; height: 40px; padding: 0 12px; font-size: 14px; border: 1px solid #dcdfe6; border-radius: 6px; outline: none; transition: border-color .2s; } .form-item input:focus { border-color: #409eff; } .btn { width: 100%; height: 42px; margin-top: 8px; font-size: 15px; color: #fff; background: #409eff; border: none; border-radius: 6px; cursor: pointer; transition: background .2s; } .btn:hover { background: #66b1ff; } /style /head body div classlogin-box h1后台管理系统/h1 !-- 表单POST 提交 -- form action methodpost autocompleteoff div classform-item label forusername账号/label input typetext idusername nameusername placeholder请输入账号 required /div div classform-item label forpassword密码/label input typepassword idpassword namepassword placeholder请输入密码 required /div button typesubmit classbtn登 录/button /form /div /body /html ?php //登录文件-采用session验证 include ../config.php; //1、接收输入的账号密码 $user$_POST[username]; $pass$_POST[password]; $sqlselect * from admin where username$user and password$pass;; $datamysqli_query($con,$sql); if($_SERVER[REQUEST_METHOD]POST){ if(mysqli_num_rows($data)0){ session_start();//开启session会话 $_SESSION[username]$user; $_SESSION[password]$pass; header(Location: index-s.php); exit(); }else{ echo scriptalert(登录失败)/script; }}2index-s.php?php //判断省去了数据库查询获取账号密码的操作 直接赋值 session_start(); if($_SESSION[username]!admin || $_SESSION[password]!123456){ //同前面的cookie header(Location: admin-s.php); } ? !DOCTYPE html html head meta charsetutf-8 title后台首页/title /head body h1后台首页/h1 p欢迎您?php echo $_SESSION[username]; ?/p pa hreflogout-s.php退出登录/a/p /body /html3logout-s.php?php // 开始会话 session_start(); // 清除 SESSION 变量并销毁会话 session_unset(); session_destroy(); // 重定向到登录页面 header(Location: admin-s.php); exit; ?3.交作业页面是和cookie一样的不过服务器多了session文件PHP study的session文件默认存放位置phpstudy_pro\phpstudy_pro\Extensions\tmp\tmp这个位置还可以通过修改配置文件来改变phpstudy_pro\phpstudy_pro\Extensions\php\php7.3.4nts\php.ini在这个文件中搜索session_save_pathsession文件里面就是用户和账号密码浏览器只存了编号三.token1.原理用来唯一标识数据包。你可以把 Token 想象成服务器在用户打开登录页时悄悄生成并塞进表单里的一张“一次性暗号纸条”同时服务器自己把这张纸条的底根锁进 Session 保险柜里当用户填写账号密码点击登录时表单就会把这张“暗号纸条”一起交回服务器服务器先看保险柜里有没有底根、有没有过期再拿出底根和用户交回的纸条用 hash_equals() 仔细核对只有完全一致且账号密码正确才放行登录成功后这张纸条立刻作废销毁并重新生成 Session ID就像一次性手环用完即撕这样即使有人偷看、伪造 Cookie 或想重复提交旧请求也因为没有服务器保险柜里的底根而无法蒙混过关。运行机制3.代码实现1token.php?php //生成Token并且将其存储在Session中 session_start(); $token bin2hex(random_bytes(16)); //将token保存到session中 $_SESSION[token]$token; $_SESSION[token_time] time(); ? !DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title后台登录/title style * { box-sizing: border-box; } body { margin: 0; min-height: 100vh; background: #f0f2f5; font-family: -apple-system, Segoe UI, Microsoft YaHei, sans-serif; } .login-box { /* 关键脱离文档流相对视口居中 */ position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 10; width: 100%; max-width: 360px; padding: 32px 28px; background: #fff; border-radius: 10px; box-shadow: 0 4px 20px rgba(0, 0, 0, .08); } .login-box h1 { margin: 0 0 24px; font-size: 20px; text-align: center; color: #333; } .form-item { margin-bottom: 18px; } .form-item label { display: block; margin-bottom: 6px; font-size: 14px; color: #555; } .form-item input { width: 100%; height: 40px; padding: 0 12px; font-size: 14px; border: 1px solid #dcdfe6; border-radius: 6px; outline: none; transition: border-color .2s; } .form-item input:focus { border-color: #409eff; } .btn { width: 100%; height: 42px; margin-top: 8px; font-size: 15px; color: #fff; background: #409eff; border: none; border-radius: 6px; cursor: pointer; transition: background .2s; } .btn:hover { background: #66b1ff; } /style /head body div classlogin-box h1后台管理系统/h1 !-- 表单POST 提交 -- form actiontoken_check.php methodpost autocompleteoff div classform-item input typehidden nametoken value?php echo $token;? label forusername账号/label input typetext idusername nameusername placeholder请输入账号 required /div div classform-item label forpassword密码/label input typepassword idpassword namepassword placeholder请输入密码 required /div button typesubmit classbtn登 录/button /form /div /body /html2Token_check?php session_start(); if ($_SERVER[REQUEST_METHOD] ! POST) { exit(非法请求); } //强制通过post方法提交 $username $_POST[username] ?? ;//从 POST 请求中取出 username 参数如果这个参数不存在就赋值为空字符串 $password $_POST[password] ?? ; $postToken $_POST[token] ?? ; // 1. 检查 session token 是否存在 if (!isset($_SESSION[token], $_SESSION[token_time])) { exit(登录失败token 不存在); } // 2. 检查 token 是否过期例如 5 分钟 if (time() - $_SESSION[token_time] 300) { unset($_SESSION[token], $_SESSION[token_time]); exit(登录失败token 已过期); } // 3. 比较 POST token 和 SESSION token if (!hash_equals((string)$_SESSION[token], (string)$postToken)) { exit(登录失败token 无效); } // 4. 验证账号密码实际项目应查数据库并用 password_verify if ($username admin $password 123456) { // token 一次性使用防止重放 unset($_SESSION[token], $_SESSION[token_time]); // 防止会话固定 session_regenerate_id(true); echo 登录成功!; } else { echo 登录失败!; }3.作业再次提交表单提示token不存在