登录  /  注册
博主信息
博文 22
粉丝 1
评论 0
访问量 19468
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
0114作业-用cookie和session分别实现登录与注册验证-php培训十期线上班
Dseven
原创
1029人浏览过

1.作业要求

用cookie和session分别实现登录与注册验证

2.作业分析

2.1流程图

2.2分析

2.2.1页面分析

-作业的显示页面为三个,一个是主页有登录和注册入口,一个是登录页面,一个是注册页面。除了显示的三个页面外,还需要一个控制分发的脚本。
-从流程图中可以看见:
未登录主页有两个出口一个是登录,一个是注册;
已登录主页有一个出口就是退出;
登录有两个出口一个是登录主页,一个是转向注册页;
注册有两个出口一个是注册主页,一个是转向登录页;
其中除了登录与注册页之间的相互跳转外,其余均应通过控制分发脚本进行处理并分发。

2.2.2数据流向

-登录页、注册页和主页退出均是通过$_GET 来传递参数供控制分发脚本进行判断。
-登录页、注册页表单中的数据均是通过$_POST来向控制分发脚本传递参数的。
-控制分发脚本处理完的参数在cookie方法中,是通过将数据序列化后存入$_COOKIE这个超全局变量中供主页调用的。

2.2.3分发控制页代码分析

  1. $users = [
  2. ['id' => 1,'email' => 'admin@php.cn','name' => 'admin','password' => '8843028fefce50a6de50acdf064ded27'],
  3. ['id' => 2,'email' => 'peter@qq.cn','name' => 'peter','password' => '5ba1a3fc5fa1363689baab6b3288def8'],
  4. ['id' => 3,'email' => 'dseven@php.cn','name' => 'dseven','password' => '84d28f2183a9f2cf67b8b08f7652f757'],
  5. ];

以上代码是建立一个二维数组,用来模拟数据表,可以实验用户登录验证的数据,其中password字段是经过加密函数加密后的字符串。

  1. $allowNames = ['index.php','log.php','reg.php'];
  2. $currentName = basename(filter_input(INPUT_SERVER,'HTTP_REFERER'));//变量中只有键名
  3. if(!in_array($currentName,$allowNames)){
  4. exit('非法来源');
  5. }

以上代码是建立一个脚本白名单,并进行来源验证,主要是防止用户直接进入控制分发页,从流程图中可以看见能进入控制分发页的只有主页、登录页和注册页,将其三个放入一个数组中形成白名单,然后用请求页的$_SERVER['HTTP_REFERER']的值来进行判断。其中basename()的作用是将路径去掉,只保留脚本名。

  1. $action = filter_input(INPUT_GET,'action',FILTER_SANITIZE_STRING);
  2. $action = strtolower($action);

以上代码是分析整理用户通过$_GET传过来的参数,以供下部进行分发判断。

  1. case 'log':
  2. if(filter_input(INPUT_SERVER,'REQUEST_METHOD') === 'POST'){
  3. $email = filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL);
  4. $email = filter_var($email,FILTER_SANITIZE_EMAIL);
  5. $password = md5(sha1(filter_input(INPUT_POST,'password'))) ;
  6. $results = array_filter($users,function ($user)use($email,$password){
  7. return $email === $user['email']&&$password === $user['password'];
  8. });
  9. if(count($results) === 1){
  10. setcookie('user',serialize(array_pop($results)));
  11. exit('<script>alert("验证通过");location.href="index.php";</script>');
  12. }else{
  13. exit('<script>alert("验证未通过,请重新登录或注册");location.href="log.php";</script>');
  14. }
  15. }
  16. break;

以上代码是switch($action)中的一个分支,主要是用来分析处理登录页面的数据。其基本步骤是:首先分析登录页面提交的数据是否通过POST方法传递,其次依次处理emailpassword的值,然后通过array_filter()和最开始建立的二维数组中的数据进行比对,第四步是将比对成功的数组的值序列化,并通过setcookie()写入COOKIE中,供主页调用。

  1. case 'reg':
  2. $email = filter_var(filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL),FILTER_SANITIZE_EMAIL);
  3. $password = md5(sha1(filter_input(INPUT_POST,'password1'))) ;
  4. $name = filter_input(INPUT_POST,'username',FILTER_SANITIZE_FULL_SPECIAL_CHARS);
  5. $id = 4;
  6. $data = compact('id','email','name','password');
  7. $i = count($users);
  8. if(array_push($users,$data) === $i+1){
  9. setcookie('user',serialize(array_pop($users)));
  10. exit('<script>alert("注册成功");location.href="index.php";</script>');
  11. }
  12. break;

以上代码是switch($action)中的一个分支,主要是用来分析处理注册页面的数据。其基本步骤是:首先用三个变量分别获取注册页面传来的三个值;其次是将三个值与ID值一起通过compact()组合成一个数组,将组合成的数组通过array_push()压入用户表信息二维数组中(注意此处只是演示,只能暂时压入,不会永久保留);第三步是将之前组合成的数组取值并进行序列化,然后通过setcookie()写入COOKIE中,供主页调用。此处需要注意的是:array_push()返回的是数组入栈后的总数量,而不是布尔值,因此不能用恒等于1来判断是否入栈成功,而要用整体数量是否加1来判断。

  1. case 'logout':
  2. if(filter_input(INPUT_COOKIE,'user')){
  3. setcookie('user',null,time()-3600);
  4. exit('<script>alert("退出成功");location.href="index.php";</script>');
  5. }
  6. break;

以上代码,是用来处理主页退出登录的请求。关键点在于用setcookie()来注销掉之前建立的$_COOKIE[user],基本原理就是给它赋一个空值,并给一个过期时间,实际上只给过期时间也可以。

2.2.4主页代码分析

  1. <?php
  2. if(filter_has_var(INPUT_COOKIE,'user')){
  3. $user = unserialize(filter_input(INPUT_COOKIE,'user'));
  4. }
  5. ?>

以上代码主要是用来,获取从控制分发页送至COOKIE的值。需要注意的是,在取值时要进行反序列化。

  1. <span>
  2. <?php if(isset($user)) :?>
  3. <a href="">
  4. <?php echo $user['name'];?> </a>
  5. <a href="" id="logout">退出</a>
  6. <?php else : ?>
  7. <a href="log.php">登录</a>
  8. <span>&#166</span>
  9. <a href="reg.php">注册</a>
  10. <?php endif ?>
  11. </span>

以上代码主要实现的是不同状态下主页显示不同的链接和信息。

3.重点和难点

3.1过滤器

-根据自己的理解其实过滤器应该是分为过滤函数和过滤器两类。其中filter_var()是属于过滤函数,FILTER_SANITIZE_EMAIL是属于过滤器也就是一种过滤规则,是过滤函数的一个参数。


个人感觉filter_var()如果加上合适的过滤器的话和filter_input()的效果基本一致,不过filter_var()不能直接从脚本外部获取输入并过滤,需要先建立一个变量并赋值之后才行。

3.2COOKIE与SESSION的理解

-感觉cookie就是浏览器中设立的一个容器,其他脚本都可以通过setcookie()来给里面装上东西,而且这个装好的东西不会随着安装脚本的消失而消失,它会一直保留在浏览器的容器中,这样别的脚本就能从中调用,达到不同脚本之间传递消息的功能。
-SESSION感觉像是比COOKIE更保密的容器,基本效果和作用都一样,不过用之前需要建立会话,用的过程中不需要过滤。

4.源代码

  1. <?php
  2. if(filter_has_var(INPUT_COOKIE,'user')){
  3. $user = unserialize(filter_input(INPUT_COOKIE,'user'));
  4. }
  5. ?>
  6. <!doctype html>
  7. <html lang="en">
  8. <head>
  9. <meta charset="UTF-8">
  10. <title>主页面</title>
  11. <link rel="stylesheet" href="css/index.css">
  12. </head>
  13. <body>
  14. <div class="header">
  15. <div class="box">
  16. <a href="">首页</a>
  17. <span>
  18. <?php if(isset($user)) :?>
  19. <a href=""><?php echo $user['name'];?></a>
  20. <a href="" id="logout">退出</a>
  21. <?php else : ?>
  22. <a href="log.php">登录</a>
  23. <span>&#166</span>
  24. <a href="reg.php">注册</a>
  25. <?php endif ?>
  26. </span>
  27. </div>
  28. </div>
  29. <script>
  30. document.querySelector('#logout').addEventListener('click',function (event) {
  31. if(confirm('是否退出')){
  32. event.preventDefault();
  33. window.location.assign('handle.php?action=logout');
  34. }
  35. });
  36. </script>
  37. </body>
  38. </html>
  1. <?php
  2. $users = [
  3. ['id' => 1,'email' => 'admin@php.cn','name' => 'admin','password' => '8843028fefce50a6de50acdf064ded27'],
  4. ['id' => 2,'email' => 'peter@qq.cn','name' => 'peter','password' => '5ba1a3fc5fa1363689baab6b3288def8'],
  5. ['id' => 3,'email' => 'dseven@php.cn','name' => 'dseven','password' => '84d28f2183a9f2cf67b8b08f7652f757'],
  6. ];
  7. //获取脚本名
  8. $allowNames = ['index.php','log.php','reg.php'];
  9. $currentName = basename(filter_input(INPUT_SERVER,'HTTP_REFERER'));//变量中只有键名
  10. if(!in_array($currentName,$allowNames)){
  11. exit('非法来源');
  12. }
  13. //请求的分发处理
  14. $action = filter_input(INPUT_GET,'action',FILTER_SANITIZE_STRING);
  15. $action = strtolower($action);
  16. switch ($action){
  17. case 'log':
  18. if(filter_input(INPUT_SERVER,'REQUEST_METHOD') === 'POST')
  19. {
  20. $email = filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL);
  21. $email = filter_var($email,FILTER_SANITIZE_EMAIL);
  22. $password = md5(sha1(filter_input(INPUT_POST,'password'))) ;
  23. $results = array_filter($users,function ($user)use($email,$password){
  24. return $email === $user['email']&&$password === $user['password'];
  25. });
  26. if(count($results) === 1){
  27. setcookie('user',serialize(array_pop($results)));
  28. exit('<script>alert("验证通过");location.href="index.php";</script>');
  29. }else{
  30. exit('<script>alert("验证未通过,请重新登录或注册");location.href="log.php";</script>');
  31. }
  32. }
  33. break;
  34. case 'reg':
  35. $email = filter_var(filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL),FILTER_SANITIZE_EMAIL);
  36. $password = md5(sha1(filter_input(INPUT_POST,'password1'))) ;
  37. $name = filter_input(INPUT_POST,'username',FILTER_SANITIZE_FULL_SPECIAL_CHARS);
  38. $id = 4;
  39. $data = compact('id','email','name','password');
  40. $i = count($users);
  41. if(array_push($users,$data) === $i+1){
  42. setcookie('user',serialize(array_pop($users)));
  43. exit('<script>alert("注册成功");location.href="index.php";</script>');
  44. }
  45. break;
  46. case 'logout':
  47. if(filter_input(INPUT_COOKIE,'user')){
  48. setcookie('user',null,time()-3600);
  49. exit('<script>alert("退出成功");location.href="index.php";</script>');
  50. }
  51. break;
  52. default:
  53. echo '未定义操作';
  54. }
  1. <?php
  2. if(filter_has_var(INPUT_COOKIE,'user')){
  3. exit('<script>alert("请不要重复登录");location.href="index.php";</script>');
  4. }
  5. ?>
  6. <!DOCTYPE html>
  7. <html lang="en">
  8. <head>
  9. <meta charset="UTF-8">
  10. <title>登录页面</title>
  11. <link rel="stylesheet" href="css/log.css">
  12. </head>
  13. <body>
  14. <h2>用户登录</h2>
  15. <div class="container">
  16. <form action="handle.php?action=log" method="post" id="log" name="log">
  17. <span>
  18. <label for="email">邮箱:</label>
  19. <input type="email" name="email" id="email" placeholder="请输入邮箱地址" >
  20. </span>
  21. <span>
  22. <label for="password">密码:</label>
  23. <input type="password" name="password" id="password" placeholder="请输入密码" >
  24. </span>
  25. <span>
  26. <button type="submit">登录</button>
  27. </span>
  28. </form>
  29. </div>
  30. <a href="reg.php">没有注册,去注册吧</a>
  31. </body>
  32. </html>

4.4注册页源代码(两种方法共用,无变化)

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>注册页面</title>
  6. <link rel="stylesheet" href="css/reg.css">
  7. </head>
  8. <body>
  9. <h2>用户注册</h2>
  10. <div class="container">
  11. <form action="handle.php?action=reg" method="post" id="reg" name="reg">
  12. <span>
  13. <label for="email">邮箱:</label>
  14. <input type="email" name="email" id="email" placeholder="请输入邮箱地址" >
  15. <label for="email"></label>
  16. </span>
  17. <span>
  18. <label for="username">昵称:</label>
  19. <input type="text" name="username" id="username" placeholder="请输入用户名"
  20. autocomplete="off" form="reg" required autofocus>
  21. <label for="username">不超过20个字符</label>
  22. </span>
  23. <span>
  24. <label for="password">密码:</label>
  25. <input type="password" name="password" id="password" placeholder="请输入密码" form="reg" required autofocus>
  26. <label for="password">不少于8位</label>
  27. </span>
  28. <span>
  29. <label for="password1">重复密码:</label>
  30. <input type="password1" name="password1" id="password1" placeholder="请重复密码" required autofocus>
  31. <label for="password1">两次密码必须一致</label>
  32. </span>
  33. <span>
  34. <button type="submit">提交注册</button>
  35. <button type="reset">重新填写</button>
  36. </span>
  37. </form>
  38. </div>
  39. <a href="log.php">已经注册了,返回登录</a>
  40. </body>
  41. </html>

4.5主页源代码(session方法)

  1. <?php
  2. session_start();
  3. if(isset($_SESSION['user'])){
  4. $user = $_SESSION['user'];
  5. }
  6. ?>
  7. <!doctype html>
  8. <html lang="en">
  9. <head>
  10. <meta charset="UTF-8">
  11. <title>主页面</title>
  12. <link rel="stylesheet" href="css/index.css">
  13. </head>
  14. <body>
  15. <div class="header">
  16. <div class="box">
  17. <a href="">首页</a>
  18. <span>
  19. <?php if(isset($user)) :?>
  20. <a href=""><?php echo $user['name'];?></a>
  21. <a href="" id="logout">退出</a>
  22. <?php else : ?>
  23. <a href="log.php">登录</a>
  24. <span>&#166</span>
  25. <a href="reg.php">注册</a>
  26. <?php endif ?>
  27. </span>
  28. </div>
  29. </div>
  30. <script>
  31. document.querySelector('#logout').addEventListener('click',function (event) {
  32. if(confirm('是否退出')){
  33. event.preventDefault();
  34. window.location.assign('handle.php?action=logout');
  35. }
  36. });
  37. </script>
  38. </body>
  39. </html>

4.6登录页源代码(session方法)

  1. <?php
  2. session_start();
  3. if(isset($_SESSION['user'])){
  4. exit('<script>alert("请不要重复登录");location.href="index.php";</script>');
  5. }
  6. //?>
  7. <!DOCTYPE html>
  8. <html lang="en">
  9. <head>
  10. <meta charset="UTF-8">
  11. <title>登录页面</title>
  12. <link rel="stylesheet" href="css/log.css">
  13. </head>
  14. <body>
  15. <h2>用户登录</h2>
  16. <div class="container">
  17. <form action="handle.php?action=log" method="post" id="log" name="log">
  18. <span>
  19. <label for="email">邮箱:</label>
  20. <input type="email" name="email" id="email" placeholder="请输入邮箱地址" >
  21. </span>
  22. <span>
  23. <label for="password">密码:</label>
  24. <input type="password" name="password" id="password" placeholder="请输入密码" >
  25. </span>
  26. <span>
  27. <button type="submit">登录</button>
  28. </span>
  29. </form>
  30. </div>
  31. <a href="reg.php">没有注册,去注册吧</a>
  32. </body>
  33. </html>

4.7控制分发页源代码(session方法)

  1. <?php
  2. session_start();
  3. $users = [
  4. ['id' => 1,'email' => 'admin@php.cn','name' => 'admin','password' => '8843028fefce50a6de50acdf064ded27'],
  5. ['id' => 2,'email' => 'peter@qq.cn','name' => 'peter','password' => '5ba1a3fc5fa1363689baab6b3288def8'],
  6. ['id' => 3,'email' => 'dseven@php.cn','name' => 'dseven','password' => '84d28f2183a9f2cf67b8b08f7652f757'],
  7. ];
  8. //设置合法请求的白名单
  9. $allowNames = ['index.php','log.php','reg.php'];
  10. //获取脚本名
  11. $currentName = basename(filter_input(INPUT_SERVER,'HTTP_REFERER'));//变量中只有键名
  12. if(!in_array($currentName,$allowNames)){
  13. exit('非法来源');
  14. }
  15. //请求的分发处理
  16. $action = filter_input(INPUT_GET,'action',FILTER_SANITIZE_STRING);
  17. $action = strtolower($action);
  18. switch ($action){
  19. case 'log':
  20. if(filter_input(INPUT_SERVER,'REQUEST_METHOD') === 'POST'){
  21. $email = filter_var(filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL),FILTER_SANITIZE_EMAIL);
  22. $password = md5(sha1(filter_input(INPUT_POST,'password'))) ;
  23. $results = array_filter($users,function ($user)use($email,$password){
  24. return $email === $user['email']&&$password === $user['password'];
  25. });
  26. if(count($results) === 1){
  27. $_SESSION['user'] = array_pop($results) ;
  28. exit('<script>alert("验证通过");location.href="index.php";</script>');
  29. }else{
  30. exit('<script>alert("验证未通过,请重新登录或注册");location.href="log.php";</script>');
  31. }
  32. }
  33. break;
  34. case 'reg':
  35. $email = filter_var(filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL),FILTER_SANITIZE_EMAIL);
  36. $password = md5(sha1(filter_input(INPUT_POST,'password1'))) ;
  37. $name = filter_input(INPUT_POST,'username',FILTER_SANITIZE_FULL_SPECIAL_CHARS);
  38. $id = 4;
  39. $data = compact('id','email','name','password');
  40. $i = count($users);
  41. if(array_push($users,$data) === $i+1){
  42. $_SESSION['user'] = array_pop($users) ;
  43. exit('<script>alert("注册成功");location.href="index.php";</script>');
  44. }
  45. break;
  46. case 'logout':
  47. if(isset($_SESSION['user'])){
  48. session_destroy();
  49. exit('<script>alert("退出成功");location.href="index.php";</script>');
  50. }
  51. break;
  52. default:
  53. echo '未定义操作';
  54. }

5.效果图

5.1未登录主页

5.2登录页面

5.3登录验证通过页面

5.4登录成功页面

5.5注册页面

5.6注册成功页面

5.7退出选择页面

批改老师:天蓬老师天蓬老师

批改状态:合格

老师批语:如果写得多了, 这个流程图,实际上已经印在大脑中了, 我写的时候,并没有画这个图, 直接写的就可以, 所以, 一定要多写, 写多了, 就形成自动记忆了
本博文版权归博主所有,转载请注明地址!如有侵权、违法,请联系admin@php.cn举报处理!
全部评论 文明上网理性发言,请遵守新闻评论服务协议
0条评论
作者最新博文
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2024 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号

  • 登录PHP中文网,和优秀的人一起学习!
    全站2000+教程免费学