首页 > 编程 > PHP > 正文

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

2019-11-21 22:06:40
字体:
来源:转载
供稿:网友

本文实例讲述了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

<?phpnamespace 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

<?phpnamespace 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>

附:模块目录

补充:小编在这里推荐一款本站的php格式化美化的排版工具帮助大家在以后的PHP程序设计中进行代码排版:

php代码在线格式化美化工具:http://tools.VeVB.COm/code/phpformat

更多关于thinkPHP相关内容感兴趣的读者可查看本站专题:《ThinkPHP入门教程》、《ThinkPHP常用方法总结》、《smarty模板入门基础教程》及《PHP模板技术总结》。

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表