当前位置:首页 > CMS教程 > Thinkphp > 列表

ThinkPHP3.2.2实现持久登录(记住我)功能的方法

发布:smiling 来源: PHP粉丝网  添加日期:2021-08-06 09:50:25 浏览: 评论:0 

这篇文章主要介绍了ThinkPHP3.2.2实现持久登录(记住我)功能的方法,涉及ThinkPHP操作cookie记录登陆信息的相关技巧,需要的朋友可以参考下,本文实例讲述了ThinkPHP3.2.2实现持久登录功能的方法,分享给大家供大家参考,具体如下:

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

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

  1. +------------+-------------+------+-----+---------+----------------+ 
  2. | Field | Type | Null | Key | Default | Extra | 
  3. +------------+-------------+------+-----+---------+----------------+ 
  4. | uid | int(11) | NO | PRI | NULL | auto_increment | 
  5. | uname | varchar(20) | YES | | NULL | | 
  6. | upwd | varchar(20) | YES | | NULL | | 
  7. | uflag | int(11) | YES | | NULL | | 
  8. | identifier | varchar(32) | YES | | NULL | | 
  9. | token | varchar(32) | YES | | NULL | | 
  10. | timeout | int(11) | YES | | NULL | | 
  11. +------------+-------------+------+-----+---------+----------------+ 

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

代码:

控制器 TestController.class.php

  1. <?php 
  2. namespace Test\Controller; 
  3. use Think\Controller; 
  4. class TestController extends Controller { 
  5.  public function login(){ 
  6.   //判断是否永久登录 
  7.   $this->checkLong(); 
  8.   //已经登录则跳转至个人中心 
  9.   if(isset($_SESSION['username'])){ 
  10.    $this->redirect('Test/ucenter'); 
  11.   }else
  12.    //判断是否存在cookie 
  13.    if(isset($_COOKIE['username'])){ 
  14.     $this->assign('username',$_COOKIE['username']); 
  15.    } 
  16.    //显示注册页 
  17.    $this->display("test"); 
  18.   } 
  19.  } 
  20.  //显示验证码 
  21.  public function verifyImg(){ 
  22.   $verify = new \Think\Verify(); 
  23.   //$verify->useZh = true; //使用中文验证码 
  24.   $verify->length = 4;  
  25.   $verify->entry(); 
  26.  } 
  27.  //验证登录 
  28.  public function check(){ 
  29.   $verify = new \Think\Verify(); 
  30.   if($verify->check(I("yzm"))){ 
  31.    //判断用户名密码 
  32.    $user = new \Test\Model\TestModel(); 
  33.    $res = $user->checkName(I("username"),I("pwd")); 
  34.    if($res === false){ 
  35.     echo "用户名或密码错误"
  36.    }else
  37.     //用户信息存入session 
  38.     session("username",$res['uname']); 
  39.     session("id",$res['uid']); 
  40.     //如果用户勾选了"记住我",则保持持久登陆 
  41.     if(I("remember")){ 
  42.      $salt = $this->random_str(16); 
  43.      //第二分身标识 
  44.      $identifier = md5($salt . md5(I("username") . $salt)); 
  45.      //永久登录标识 
  46.      $token = md5(uniqid(rand(), true)); 
  47.      //永久登录超时时间(1周) 
  48.      $timeout = time()+3600*24*7; 
  49.      //存入cookie 
  50.      setcookie('auth',"$identifier:$token",$timeout); 
  51.      $user->saveRemember($res['uid'],$identifier,$token,$timeout); 
  52.     } 
  53.     //把用户名存入cookie,退出登录后在表单保存用户名信息 
  54.     setcookie('username',I('username'),time()+3600*24); 
  55.     //跳转至会员中心 
  56.     $this->redirect('Test/ucenter'); 
  57.    } 
  58.   }else
  59.    echo "输入错误"
  60.   } 
  61.  }  
  62.  //测试strstr函数 
  63.  public function strstrtest(){ 
  64.   $param = "Think\Verify"
  65.   //第三个参数为true,返回'Think';没有第三个参数,返回'\Verify' 
  66.   $name = strstr($param,'\\',true); 
  67.   echo $name
  68.  } 
  69.  //用户中心 
  70.  public function ucenter(){ 
  71.   //判断是否永久登录 
  72.   $this->checkLong(); 
  73.   $this->assign("session",$_SESSION); 
  74.   $this->display("ucenter"); 
  75.  } 
  76.  //退出登录 
  77.  public function loginout(){ 
  78.   session(null); 
  79.   setcookie('auth''', time()-1); 
  80.   $this->redirect("Test/login"); 
  81.  } 
  82.  //生成随机数,用于生成salt 
  83.  public function random_str($length){ 
  84.   //生成一个包含 大写英文字母, 小写英文字母, 数字 的数组 
  85.   $arr = array_merge(range(0, 9), range('a''z'), range('A''Z')); 
  86.   $str = ''
  87.   $arr_len = count($arr); 
  88.   for ($i = 0; $i < $length$i++){ 
  89.    $rand = mt_rand(0, $arr_len-1); 
  90.    $str.=$arr[$rand]; 
  91.   } 
  92.   return $str
  93.  } 
  94.  //判断是否持久登录 
  95.  public function checkLong(){ 
  96.   $check = new \Test\Model\TestModel(); 
  97.   $is_long = $check->checkRemember(); 
  98.   if($is_long === false){ 
  99.   }else
  100.    session("username",$is_long['uname']); 
  101.    session("id",$is_long['uid']); 
  102.   } 
  103.  } 

模型 TestModel.class.php

  1. <?php 
  2. namespace Test\Model; 
  3. use Think\Model; 
  4. class TestModel extends Model{ 
  5.  //验证登录信息 
  6.  public function checkName($name,$pwd){ 
  7.   $admin = M("admin"); 
  8.   $info = $admin->getByUname($name); 
  9.   if($info != null){ 
  10.    //验证密码 
  11.    if($info['upwd'] == $pwd){ 
  12.     return $info
  13.    }else
  14.     return false; 
  15.    } 
  16.   }else
  17.    return false; 
  18.   } 
  19.  } 
  20.  //当用户勾选"记住我" 
  21.  public function saveRemember($uid,$identifier,$token,$timeout){ 
  22.   $admin = M("admin"); 
  23.   $data['identifier'] = $identifier
  24.   $data['token'] = $token
  25.   $data['timeout'] = $timeout
  26.   $where = " uid = ".$uid
  27.   $res = $admin->data($data)->where($where)->save(); 
  28.   return $res
  29.  } 
  30.  //验证用户是否永久登录(记住我) 
  31.  public function checkRemember(){ 
  32.   $arr = array(); 
  33.   $now = time(); 
  34.   list($identifier,$token) = explode(':',$_COOKIE['auth']); 
  35.   if (ctype_alnum($identifier) && ctype_alnum($token)){ 
  36.    $arr['identifier'] = $identifier
  37.    $arr['token'] = $token
  38.   }else
  39.    return false; 
  40.   } 
  41.   $admin = M("admin"); 
  42.   $info = $admin->getByidentifier($arr['identifier']); 
  43.   if($info != null){ 
  44.    if($arr['token'] != $info['token']){ 
  45.     return false; 
  46.    }else if($now > $info['timeout']){ 
  47.     return false; 
  48.    }else
  49.     return $info
  50.    } 
  51.   }else
  52.    return false; 
  53.   } 
  54.  } 

视图 登录页 test.html

  1. <DOCTYPE html> 
  2. <html lang="en"> 
  3. <head> 
  4.  <meta charset="UTF-8"> 
  5.  <title>Document</title> 
  6. </head> 
  7. <body> 
  8. <form action="__CONTROLLER__/check" method="post"> 
  9. <if condition="$username neq null"> 
  10.  <input type="text" name="username" placeholder="用户名" value="{$username}"><br> 
  11. <else /> 
  12.  <input type="text" name="username" placeholder="用户名"><br>  
  13. </if> 
  14. <input type="password" name="pwd" placeholder="密码"><br> 
  15. <input type="text" name="yzm" placeholder="验证码"><img src="__CONTROLLER__/verifyImg" onClick="this.src=this.src+'?'+Math.random()"><br> 
  16. <input type="checkbox" name="remember" id="remember"><label for="remember">记住我</label> 
  17. <input type="submit" value="提交">  
  18. </form> 
  19. </body> 
  20. </html> 

视图 个人中心 ucenter.html

  1. <DOCTYPE html> 
  2. <html lang="en"> 
  3. <head> 
  4.  <meta charset="UTF-8"> 
  5.  <title>Documenttitle> 
  6. </head> 
  7. <body> 
  8.  <if condition="$session['username'] neq null"> 
  9.  <i>{$session.username},</i> 
  10.  <else /> 
  11.  <i>游客,</i> 
  12.  </if> 
  13.  欢迎您<br> 
  14.  <a href="__CONTROLLER__/loginout">退出登录</a> 
  15. </body> 
  16. </html>

Tags: ThinkPHP3 2 2持久登录

分享到: