开发企业网站5 --后台登录功能

\color{rgba(254, 67, 101, .8)}{在后台首页index.html代码中,给用户名和密码加上name}

<div class="row cl">
        <label class="form-label col-xs-3"><i class="Hui-iconfont">&#xe60d;</i></label>
        <div class="formControls col-xs-8">
          <input id="" name="username" type="text" placeholder="账户" class="input-text size-L">
        </div>
      </div>
      <div class="row cl">
        <label class="form-label col-xs-3"><i class="Hui-iconfont">&#xe60e;</i></label>
        <div class="formControls col-xs-8">
          <input id="" name="password" type="password" placeholder="密码" class="input-text size-L">
        </div>
      </div>

\color{rgba(254, 67, 101, .8)}{保持登录状态也是没有值的,给他一个值value=1}

<div class="row cl">
        <div class="formControls col-xs-8 col-xs-offset-3">
          <label for="online">
            <input type="checkbox" name="online" id="online" value="1">
            使我保持登录状态</label>
        </div>
      </div>

\color{rgba(254, 67, 101, .8)}{那么首台登陆首页传递到login.php的数据一共四个}
\color{rgba(254, 67, 101, .8)}{账号、密码、验证码和保持登录状态}

image.png

\color{rgba(254, 67, 101, .8)}{后台登陆首页写完之后,就在login.php页面接收传递过来的四个数据}
\color{rgba(254, 67, 101, .8)}{并进行验证}

require_once('init.php');
    $code = $_POST['code'];


    //后台登录首页index.html传递过来的四个数据:
    //username、password、online(保持登录状态)、$code(验证码)
    $username = $_POST['username'];
    $password = $_POST['password'];
    $online = $_POST['online'];

    //在这里要进行判断
    //账号密码验证码不能为空,但是保持登录状态可以不选
    if(empty($username) || empty($password)){
        show_message('账号或密码为空', 'index.php?m=admin&c=index');
    }
    
    if(empty($code)){
        show_message('验证码为空', 'index.php?m=admin&c=index');
    }


    //将 $code接收到的用户输入验证码和系统随机出来的验证码$_SESSION['verify']进行比较:
    if(strtolower($code) != $_SESSION['verify']){
        //如果用户输入错误,就提示验证码错误并且刷新验证码
        //如果输入正确,不做任何反应
        show_message('验证码错误', 'index.php?m=admin&c=index');
    }

\color{rgba(254, 67, 101, .8)}{因为验证要弹出窗口,还要跳转页面,所以封装一个函数}
\color{rgba(254, 67, 101, .8)}{这个函数有两个参数,一个是提示信息,一个是跳转页面}

//如果用户在后台登录页面输入信息错误,则提示并再次进入此页面
//参数是在后台登录界面login.php进行逻辑判断时传过来的
    function show_message($msg, $url){
      die("<script> alert('$msg'); location.href=' $url'; </script>");
    }

\color{rgba(254, 67, 101, .8)}{这个函数的参数msg就是login.php页面进行判断时给的值}

\color{rgba(254, 67, 101, .8)}{这个函数还可以写得更好一点:}

跳转页面可以这样直接写url,也可以用history.back()回到上一页面
还可以用history.go(1);正数就是前进多少个页面,负数就是向后退多少个页面
history.go(-1);就相当于history.back()

\color{rgba(254, 67, 101, .8)}{可以把参数url默认值设置为null,再进行判断}
\color{rgba(254, 67, 101, .8)}{如果给url就使用给定的url}
\color{rgba(254, 67, 101, .8)}{如果没有给url就回到上一页}
\color{rgba(53, 93, 129, .8)}{但是用history.go(-1);是存在一定问题的,例如传的参数没有给url}
\color{rgba(53, 93, 129, .8)}{就会回到上一页,但是这里是没有上一页的,只会留在当前页面}
\color{rgba(53, 93, 129, .8)}{由于上一页、这里的当前页是之前浏览器缓存过的,所以浏览器会直接提取缓存}
\color{rgba(53, 93, 129, .8)}{所以点击验证码不会刷新}

//如果用户在后台登录页面输入信息错误,则提示并再次进入此页面
//参数是在后台登录界面login.php进行逻辑判断时传过来的
function show_message($msg, $url=null){
    if(!empty($url)){
        die("<script> alert('$msg'); location.href=' $url'; </script>");
    }else{
        die("<script> alert('$msg'); history.go(-1); </script>");
    }
}

\color{rgba(254, 67, 101, .8)}{还有一个问题是,因为保持登录没有勾选,就会报notice错误}
\color{rgba(254, 67, 101, .8)}{所以在入口文件直接屏蔽掉所有页面的notice错误}

error_reporting(E_ALL ^ E_NOTICE);

\color{rgba(254, 67, 101, .8)}{确认了接收到数据之后,开始验证账号密码的正确性}

\color{rgba(254, 67, 101, .8)}{这些数据应当保存在数据库中}
\color{rgba(254, 67, 101, .8)}{所以先用navicat先建一个表}
\color{rgba(254, 67, 101, .8)}{主键要在左下角勾选自增长和无符号}

image.png

\color{rgba(254, 67, 101, .8)}{然后点添加栏位,增加行}

image.png

\color{rgba(254, 67, 101, .8)}{账号要唯一,就要点击索引设置为唯一}

image.png

\color{rgba(254, 67, 101, .8)}{密码因为用md5加密,无论多少位密码加密出来都是32位,所以用char,长度32}

image.png

\color{rgba(254, 67, 101, .8)}{再加一个昵称}

image.png

\color{rgba(254, 67, 101, .8)}{因为这里用的模板还有登陆次数、登陆ip和登陆时间}
\color{rgba(254, 67, 101, .8)}{所以这三项也要建在数据表中}
\color{rgba(254, 67, 101, .8)}{具体存储在数据库的内容字段根据具体模板设定}

image.png

\color{rgba(254, 67, 101, .8)}{登陆次数:}

image.png

\color{rgba(254, 67, 101, .8)}{登陆ip}

image.png

\color{rgba(254, 67, 101, .8)}{登陆时间:}
\color{rgba(254, 67, 101, .8)}{默认值如图中选空字符串会报错}
\color{rgba(254, 67, 101, .8)}{应该取消右边勾选的允许空值,不打勾就是允许为空}
\color{rgba(254, 67, 101, .8)}{然后下面默认值选NULL}

image.png

\color{rgba(254, 67, 101, .8)}{后台跟前台不一样,后台不需要注册,所以需要现在数据库中写入第一个管理员账户}
\color{rgba(254, 67, 101, .8)}{登陆这个账号之后去后台添加管理员,以及给管理员分配账号密码}

\color{rgba(254, 67, 101, .8)}{点击查询之后输入代码,也可以直接在表里填数据}

INSERT into admin (username, password, nickname)values ('admin', md5('123'), '超人');

\color{rgba(254, 67, 101, .8)}{再点运行,表里就有数据了,此时已经创建好了第一个管理员账号}

image.png

\color{rgba(254, 67, 101, .8)}{将之前封装的查询函数库db.php复制到includes(包含的意思)文件夹中来}
\color{rgba(254, 67, 101, .8)}{然后在入口文件将db.php文件引入}

\color{rgba(254, 67, 101, .8)}{在入口文件idnex.php引入之前封装的数据库查询函数}

//引入之前写好的数据库查询函数库
    require_once('includes/db.php');

\color{rgba(254, 67, 101, .8)}{查询这个管理员账号:}
\color{rgba(254, 67, 101, .8)}{在后台登录界面登陆后}

//验证账号密码是否正确
    //验证账号是否存在 -> 验证密码是否正确,验证完成后登陆成功跳转到后台首页

    //这里需要建库,要验证的数据都来自数据库
    //使用之前的1803库,在这个库下建表admin
    //将之前封装的查询函数库db.php复制到includes(包含的意思)文件夹中来
    $sql = "select * from admin where username='$username' limit 1";
    $row = get_row($sql);
    print_r($row);
image.png

\color{rgba(254, 67, 101, .8)}{这里能查到数据就表示之前的db.php数据库查询函数可以用}
\color{rgba(254, 67, 101, .8)}{验证账号密码是否正确,能收到OK表示成功}

//验证账号密码是否正确
    //验证账号是否存在 -> 验证密码是否正确,验证完成后登陆成功跳转到后台首页

    //这里需要建库,要验证的数据都来自数据库
    //使用之前的1803库,在这个库下建表admin
    //将之前封装的查询函数库db.php复制到includes(包含的意思)文件夹中来
    $sql = "select * from admin where username='$username' limit 1";
    $row = get_row($sql);

    //验证账号是否正确,如果为空,就弹出提示信息
    if(empty($row)){
        show_message('账号不存在', 'index.php?m=admin&c=index');
    }


    //验证密码,把登录界面接收到的密码和之前的密码进行对比
    //需要两者都是经过md5处理的才行
    if($row['password'] != md5($password)){
        show_message('密码错误', 'index.php?m=admin&c=index');
    }
    
    echo 'OK';
    header('location:index.php?m=admin&c=main');

上面的echo 'OK';使用于测试,实际写的话要用header跳转到后台首页去
image.png

\color{rgba(254, 67, 101, .8)}{接下来进入后台首页,在admin文件夹下建main.php文件做后台主页}

\color{rgba(254, 67, 101, .8)}{有main.php就要有main.html}
\color{rgba(254, 67, 101, .8)}{所以,还要在templates➝admin下建一个main.html}

\color{rgba(254, 67, 101, .8)}{无论写什么,先把初始化文件init.php包含进来,然后显示后端首页}

<?php
    require_once('init.php');
    $smarty->display('main.html');
?>

\color{rgba(254, 67, 101, .8)}{将H-ui的后端首页代码复制到main.html中}

\color{rgba(254, 67, 101, .8)}{将代码中的链接加入smarty代码}

<{$smarty.const.__STATIC__}>访问自定义常量

image.png

\color{rgba(254, 67, 101, .8)}{中间看不到的部分是另一个页面}

\color{rgba(254, 67, 101, .8)}{在网页中嵌入一个页面}

image.png

\color{rgba(254, 67, 101, .8)}{内嵌页面要用target:\_self}

target: 页面打开方式
_self(缺省) 在本页面打开
_blank 在新窗口打开页面
framename 在iframe窗口中打开
_top 在顶级窗口打开
_parent 在父窗口(上一级窗口)打开(如果在一个内嵌的窗口中点击链接,那么打开的新窗口会显示在外面这个父窗口中)

\color{rgba(254, 67, 101, .8)}{模板的后端页面就是用嵌入页面做的}

\color{rgba(254, 67, 101, .8)}{嵌入的页面也要通过入口文件,所以不能直接给路径}

\color{rgba(254, 67, 101, .8)}{要这样写index.php?m=admin\&c=welcome;}

\color{rgba(254, 67, 101, .8)}{然后在admin页面建一个welcome.php文件}

<?php
//检测是否通过入口访问
    require_once('init.php');
    
    $smarty->display('welcome.html');//调用welcome页面
?>

\color{rgba(254, 67, 101, .8)}{还需要在templates文件夹中建一个welcome.html文件}

\color{rgba(254, 67, 101, .8)}{再将H-ui的welcome.html文件源码复制过来}


\color{rgba(254, 67, 101, .8)}{之前在login.php页面验证账号密码通过,并登陆之后}

\color{rgba(254, 67, 101, .8)}{虽然验证成功了,但是是在login.php页面验证的,跳到main.php页面其实什么都没有做}

\color{rgba(254, 67, 101, .8)}{所以,在main.php页面并不知道是谁登陆的}

\color{rgba(254, 67, 101, .8)}{所以,login.php页面要用session传递用户信息到main.php页面}
$_SESSION['admin'] = $row;

\color{rgba(254, 67, 101, .8)}{把row数组取名为admin传递给main.php}


\color{rgba(254, 67, 101, .8)}{在封装管理员登录信息函数的过程中,发现一个bug,验证码不显示}

\color{rgba(254, 67, 101, .8)}{最终发现问题是要在验证码函数的header前一句清缓存}

ob_clean();
header("content-type: image/png;");

\color{rgba(254, 67, 101, .8)}{在处理好验证码不显示的问题之后,}
\color{rgba(254, 67, 101, .8)}{因为通过login.php传递到main.php页面的信息是一个数组}
\color{rgba(254, 67, 101, .8)}{这个数组就是登陆账号的管理员信息,将他在function.php中封装成一个格式化输出函数}

//封装格式化输出函数:输出内容:登录管理员账号的信息
    function dump($data){
        echo '<pre>';
        print_r($data);
        echo '</pre>';
    }

\color{rgba(254, 67, 101, .8)}{封装好之后,}
\color{rgba(254, 67, 101, .8)}{在main.php页面接收这个数组}

dump($_SESSION['admin']);

输入网址: www.yixing666.com/index.php?m=admin&c=index

\color{rgba(254, 67, 101, .8)}{进入后端登录界面,输入账号后,进入admin.php界面,显示以下信息}
\color{rgba(254, 67, 101, .8)}{证明登录用户的信息成功的传递到了main.php}

image.png

\color{rgba(254, 67, 101, .8)}{在main.php页面将管理员信息进行分配}
\color{rgba(254, 67, 101, .8)}{在main.html页面把管理员名字替换成用户的实际账号名:}
main.php页面:

<?php
    require_once('init.php');
    //分配admin到main.html,在main.html页面通过<{$admin.nickname}>接收
    $smarty->assign('admin', $_SESSION['admin']);
    $smarty->display('main.html');//通过模板显示main.html
?>

\color{rgba(254, 67, 101, .8)}{main.html页面,也就是后台首页}

<li><{$admin.nickname}></li>

\color{rgba(254, 67, 101, .8)}{原本是超级管理员,现已被替换成数据库中预存的账户名:超人}

image.png
image.png

\color{rgba(254, 67, 101, .8)}{这里还有一种写法,main.php中不分配session,直接在main.html页面中写:}

<li><{$smarty.session.admin.nickname}></li>

\color{rgba(254, 67, 101, .8)}{可以得到同样的结果}

image.png

\color{rgba(254, 67, 101, .8)}{继续把admin同样替换为username}

<a href="#" class="dropDown_A"><{$smarty.session.admin.username}> <i class="Hui-iconfont">&#xe6d5;</i></a>

\color{rgba(254, 67, 101, .8)}{继续通过在login.php页面增加sql语句添加登陆时间、次数和ip进入数据库}

 //修改登录时间、次数,ip
    $login_time= date('Y-m-d H:i:s');
    //获取客户端 IP
    //$_SERVER 超全局数组 可以拿到用户的服务器信息(IPO地址、登陆时间等)
    //SERVER_ADDR就是这个超全局数组的IP的索引。用它可以获取到IP地址
    $login_ip = $_SERVER['SERVER_ADDR'];
    $sql = "update admin set login_time='$login_time', login_ip='$login_ip', login_num=login_num+1 where id={$row['id']}";

    //execute返回上面受影响的sql语句中的参数
    execute($sql);

\color{rgba(254, 67, 101, .8)}{然后通过smarty把数据库的数据点出来显示在welcome.html页面}


<p class="f-20 text-success">欢迎使用H-ui.admin <span class="f-14">v3.1</span>后台模版!</p>
    <p>登录次数:<{$smarty.session.admin.login_num+1}> </p>

    <{if $smarty.session.admin.login_time > 0}>
    <p>上次登录IP:<{$smarty.session.admin.login_ip}>  上次登录时间:<{$smarty.session.admin.login_time}></p>
    <{else}>
    <p>上次登录时间:第一次登陆</p>
    <{/if}>
image.png

\color{rgba(254, 67, 101, .8)}{可以登陆之后,还要做一个功能}
\color{rgba(254, 67, 101, .8)}{就是已经登录的账号,如果进入到登录界面会自动跳转到后台首页}
\color{rgba(254, 67, 101, .8)}{而不需要再次输入账号密码重新验证一次}

\color{rgba(254, 67, 101, .8)}{现在只要退到登录页面,就要重新输入账号密码}
\color{rgba(254, 67, 101, .8)}{可以进行判断,只要已经登录,就自动跳转到后台首页}
\color{rgba(254, 67, 101, .8)}{判断:如果登录就会有session产生,没有登录就不会有,所以}
\color{rgba(254, 67, 101, .8)}{通过判断session是否为空,来确定是否跳转}

//判断是否已经登录,如果已经登录,就跳转到后台主页
    if( !empty($_SESSION['admin'])){
        header("location:index.php?m=admin&c=main");
    }

\color{rgba(254, 67, 101, .8)}{这样写能解决已经登陆之后,进入登录界面会自动跳转到后台首页}
\color{rgba(254, 67, 101, .8)}{但是换一个浏览器也不用登录,直接就进去了,这样不对}
\color{rgba(254, 67, 101, .8)}{应该要换一个浏览器,就要重新登陆一次才对}
\color{rgba(254, 67, 101, .8)}{判断:除了特定页面之外,后台其他的页面必须登陆成功才可以访问}
\color{rgba(254, 67, 101, .8)}{所以,要先定义一个不需要登录验证的页面,写一个数组:}

$not_auth_login = ['index', 'login', 'verify'];

\color{rgba(254, 67, 101, .8)}{除了上面这几个页面之外,其他的页面都需要登陆验证}
\color{rgba(254, 67, 101, .8)}{在init.php(初始化)文件进行验证}

 //登陆需要验证,这就需要先定义哪些页面不需要验证的,下面这三个页面就是不要验证的
    //in_array  要在数组 $not_auth_login 中搜索的值 $c,
    //下面代码表示,如果$c不在数组中($c='文件名' url的最后一项)
    //如:http://yixing666.com/index.php?m=admin&c=main
    //如果$c不在数组中,且session为空的话,就没登陆,就跳转到登录页面
    $not_auth_login = ['index', 'login', 'verify'];
    if( !in_array($c, $not_auth_login) && empty($_SESSION['admin'])){
        header('location:idnex.php?m=admin&c=index');die();
    }

\color{rgba(254, 67, 101, .8)}{登陆功能做好后,继续做退出的功能}

\color{rgba(254, 67, 101, .8)}{在首台首页点击退出按钮之后,跳转到php界面处理退出流程}

\color{rgba(254, 67, 101, .8)}{在main.html页面,把退出的地址先写上:}

<li><a href="index.php?m=admin&c=logout">退出</a></li>

\color{rgba(254, 67, 101, .8)}{然后在后台文件夹admin下建立一个logout.php文件处理退出业务}
\color{rgba(254, 67, 101, .8)}{流程:清理掉session,并跳转到登录页面就完成了}

\color{rgba(254, 67, 101, .8)}{logout.php页面:}
\color{rgba(254, 67, 101, .8)}{后台首页接收到用户点击退出之后,跳转到这个页面进行处理}

//不管是什么,只要新建一个文件,就先包含初始化文件进来
    require_once('init.php');
    //退出功能逻辑: 清理掉session并跳转到登录界面
    //unset() 销毁指定的变量
    unset($_SESSION['admin']);
    header("location:index.php?m=admin&c=index");

\color{rgba(254, 67, 101, .8)}{处理完成之后,点击退出,再登陆,过程没问题,这个登陆功能才算是完成了}

image.png

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 三公子在“给时间做一次大扫除”中说道:“人这一辈子,唯一能够百分百属于自己,自由被支配的东西,就两个,一个...
    M家的大小姐阅读 990评论 0 0
  • 欲飞结——兼致程灵素 浇水、除草,理顺每一枚叶片之后,坐在石矶上,看鸟影掠过水面,剪羽回环啼声填满整个空谷 日复一...
    宁木紫菀阅读 320评论 0 3
  • 童年的故事五彩缤纷,童年的故事精彩纷呈,在斑斓的童年中,许许多多的趣事就像五彩的奇石,零零碎碎地点缀着童年的色彩,...
    印第安老麻雀阅读 205评论 0 0
  • 如果没有分手,今天会过三周年,已经想好了给你买什么礼物,穿什么衣服飞奔过去找你。跟你聊天,游戏,看剧,什么都不用干...
    喵土土阅读 471评论 0 0
  • 如何在一篇文章中写好细节呢?下面介绍几个常用的方法: 一、场面描写 写作中经常会遇见场面描写,比如事情发生的场面、...
    哈戳戳阅读 2,312评论 0 1

友情链接更多精彩内容