本文实例讲述了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>
附:模块目录
补充:小编在这里推荐一款本站的php格式化美化的排版工具帮助大家在以后的PHP程序设计中进行代码排版:
php代码在线格式化美化工具:http://tools.phpstudy.net/code/phpformat
更多关于thinkPHP相关内容感兴趣的读者可查看本站专题:《ThinkPHP入门教程》、《ThinkPHP常用方法总结》、《smarty模板入门基础教程》及《PHP模板技术总结》。
希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。
本文地址:https://www.stayed.cn/item/26032
转载请注明出处。
本站部分内容来源于网络,如侵犯到您的权益,请 联系我