• 技术文章 >后端开发 >php教程

    ThinkPHP3.2.2实现持久登录功能的方法

    不言不言2018-05-05 15:16:50原创709
    这篇文章主要介绍了ThinkPHP3.2.2实现持久登录(记住我)功能的方法,涉及ThinkPHP操作cookie记录登陆信息的相关技巧,需要的朋友可以参考下

    本文实例讲述了ThinkPHP3.2.2实现持久登录功能的方法。分享给大家供大家参考,具体如下:

    实现持久登录,即用户在登录时,勾选了"记住我"之后,无论是否关闭浏览器,只要不退出登录,在指定的时间内始终保持登录状态(缺点是在另一台电脑上登录过后,之前那台电脑就不能继续保持登录状态)。

    首先,持久登陆使用 cookie 实现,但是 cookie 中不能保存用户密码这样重要的信息,即使加密过。解决方案是在用户登录表中新建3个字段identifier:第二身份标识,token:永久登录标识,timeout:永久登录超时时间。

    +------------+-------------+------+-----+---------+----------------+
    | Field | Type | Null | Key | Default | Extra |
    +------------+-------------+------+-----+---------+----------------+
    | uid | int(11) | NO | PRI | NULL | auto_increment |
    | uname | varchar(20) | YES | | NULL | |
    | upwd | varchar(20) | YES | | NULL | |
    | uflag | int(11) | YES | | NULL | |
    | identifier | varchar(32) | YES | | NULL | |
    | token | varchar(32) | YES | | NULL | |
    | timeout | int(11) | YES | | NULL | |
    +------------+-------------+------+-----+---------+----------------+

    在用户勾选了"记住我"登录时,应该生成一个唯一的 identifier,一个唯一的 token,并且设置一个过期时间 timeout,把两个代表身份的值写入cookie,设置 cookie 过期时间为 timeout,例如:setcookie('auth',"$identifier:$token",$timeout); 同时把三个值插入数据表;当用户再一次访问网站时,首先判断 cookie 中是否含有 auth,如果含有,则去数据库中进行身份比对(identifier 和 token),比对成功时,把用户信息写入 session,同时用户保持登录状态。

    代码:

    控制器 TestController.class.php

    <?php
    namespace Test\Controller;
    use Think\Controller;
    class TestController extends Controller {
     public function login(){
      //判断是否永久登录
      $this->checkLong();
      //已经登录则跳转至个人中心
      if(isset($_SESSION['username'])){
       $this->redirect('Test/ucenter');
      }else{
       //判断是否存在cookie
       if(isset($_COOKIE['username'])){
        $this->assign('username',$_COOKIE['username']);
       }
       //显示注册页
       $this->display("test");
      }
     }
     //显示验证码
     public function verifyImg(){
      $verify = new \Think\Verify();
      //$verify->useZh = true; //使用中文验证码
      $verify->length = 4; 
      $verify->entry();
     }
     //验证登录
     public function check(){
      $verify = new \Think\Verify();
      if($verify->check(I("yzm"))){
       //判断用户名密码
       $user = new \Test\Model\TestModel();
       $res = $user->checkName(I("username"),I("pwd"));
       if($res === false){
        echo "用户名或密码错误";
       }else{
        //用户信息存入session
        session("username",$res['uname']);
        session("id",$res['uid']);
        //如果用户勾选了"记住我",则保持持久登陆
        if(I("remember")){
         $salt = $this->random_str(16);
         //第二分身标识
         $identifier = md5($salt . md5(I("username") . $salt));
         //永久登录标识
         $token = md5(uniqid(rand(), true));
         //永久登录超时时间(1周)
         $timeout = time()+3600*24*7;
         //存入cookie
         setcookie('auth',"$identifier:$token",$timeout);
         $user->saveRemember($res['uid'],$identifier,$token,$timeout);
        }
        //把用户名存入cookie,退出登录后在表单保存用户名信息
        setcookie('username',I('username'),time()+3600*24);
        //跳转至会员中心
        $this->redirect('Test/ucenter');
       }
      }else{
       echo "输入错误";
      }
     } 
     //测试strstr函数
     public function strstrtest(){
      $param = "Think\Verify";
      //第三个参数为true,返回'Think';没有第三个参数,返回'\Verify'
      $name = strstr($param,'\\',true);
      echo $name;
     }
     //用户中心
     public function ucenter(){
      //判断是否永久登录
      $this->checkLong();
      $this->assign("session",$_SESSION);
      $this->display("ucenter");
     }
     //退出登录
     public function loginout(){
      session(null);
      setcookie('auth', '', time()-1);
      $this->redirect("Test/login");
     }
     //生成随机数,用于生成salt
     public function random_str($length){
      //生成一个包含 大写英文字母, 小写英文字母, 数字 的数组
      $arr = array_merge(range(0, 9), range('a', 'z'), range('A', 'Z'));
      $str = '';
      $arr_len = count($arr);
      for ($i = 0; $i < $length; $i++){
       $rand = mt_rand(0, $arr_len-1);
       $str.=$arr[$rand];
      }
      return $str;
     }
     //判断是否持久登录
     public function checkLong(){
      $check = new \Test\Model\TestModel();
      $is_long = $check->checkRemember();
      if($is_long === false){
      }else{
       session("username",$is_long['uname']);
       session("id",$is_long['uid']);
      }
     }
    }

    模型 TestModel.class.php

    <?php
    namespace Test\Model;
    use Think\Model;
    class TestModel extends Model{
     //验证登录信息
     public function checkName($name,$pwd){
      $admin = M("admin");
      $info = $admin->getByUname($name);
      if($info != null){
       //验证密码
       if($info['upwd'] == $pwd){
        return $info;
       }else{
        return false;
       }
      }else{
       return false;
      }
     }
     //当用户勾选"记住我"
     public function saveRemember($uid,$identifier,$token,$timeout){
      $admin = M("admin");
      $data['identifier'] = $identifier;
      $data['token'] = $token;
      $data['timeout'] = $timeout;
      $where = " uid = ".$uid;
      $res = $admin->data($data)->where($where)->save();
      return $res;
     }
     //验证用户是否永久登录(记住我)
     public function checkRemember(){
      $arr = array();
      $now = time();
      list($identifier,$token) = explode(':',$_COOKIE['auth']);
      if (ctype_alnum($identifier) && ctype_alnum($token)){
       $arr['identifier'] = $identifier;
       $arr['token'] = $token;
      }else{
       return false;
      }
      $admin = M("admin");
      $info = $admin->getByidentifier($arr['identifier']);
      if($info != null){
       if($arr['token'] != $info['token']){
        return false;
       }else if($now > $info['timeout']){
        return false;
       }else{
        return $info;
       }
      }else{
       return false;
      }
     }
    }

    视图 登录页 test.html

    <DOCTYPE html>
    <html lang="en">
    <head>
     <meta charset="UTF-8">
     <title>Document</title>
    </head>
    <body>
    <form action="__CONTROLLER__/check" method="post">
    <if condition="$username neq null">
     <input type="text" name="username" placeholder="用户名" value="{$username}"><br>
    <else />
     <input type="text" name="username" placeholder="用户名"><br> 
    </if>
    <input type="password" name="pwd" placeholder="密码"><br>
    <input type="text" name="yzm" placeholder="验证码"><img src="__CONTROLLER__/verifyImg" onClick="this.src=this.src+'?'+Math.random()"><br>
    <input type="checkbox" name="remember" id="remember"><label for="remember">记住我</label>
    <input type="submit" value="提交"> 
    </form>
    </body>
    </html>

    视图 个人中心 ucenter.html

    <DOCTYPE html>
    <html lang="en">
    <head>
     <meta charset="UTF-8">
     <title>Documenttitle>
    </head>
    <body>
     <if condition="$session['username'] neq null">
     <i>{$session.username},</i>
     <else />
     <i>游客,</i>
     </if>
     欢迎您<br>
     <a href="__CONTROLLER__/loginout">退出登录</a>
    </body>
    </html>

    附:模块目录

    相关推荐:

    thinkphp3.2.2实现生成多张缩略图的方法,thinkphp3.2.2多张_PHP教程


    以上就是ThinkPHP3.2.2实现持久登录功能的方法的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:ThinkPHP3.2.2 php 功能
    上一篇:thinkphp3.x自定义Action、Model及View的简单实现方法 下一篇:ThinkPHP实现附件上传功能
    20期PHP线上班

    相关文章推荐

    • 【活动】充值PHP中文网VIP即送云服务器• 【吐血整理】40+个PHP面试题附答案(实战经验)• PHP网站安装程序制作的原理、步骤、注意事项和示例代码_PHP教程• PHP 写文本日志实现代码_PHP教程• PHP5.3.1 不再支持ISAPI_PHP教程• PHP_MySQL教程-第三天 基本函数第1/2页_PHP教程
    1/1

    PHP中文网