ThinkPHP 3.2.2 实现持久登录 ( 记住我 )
来源:互联网 发布:ssh 命令 指定端口 编辑:程序博客网 时间:2024/06/05 15:14
实现持久登录,即用户在登录时,勾选了"记住我"之后,无论是否关闭浏览器,只要不退出登录,在指定的时间内始终保持登录状态(缺点是在另一台电脑上登录过后,之前那台电脑就不能继续保持登录状态)。
首先,持久登陆使用 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>Document</title></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持久登录、记住我功能实现:http://blog.csdn.net/clh604/article/details/20282945
php生成包含数字,大小写英文字母的随机字符串:http://www.oschina.net/code/snippet_616695_22223
- ThinkPHP 3.2.2 实现持久登录 ( 记住我 )
- ThinkPHP 3.2.2 实现持久登录 ( 记住我 )
- php持久登录、记住我功能实现
- php持久登录、记住我功能实现
- php持久登录、记住我功能实现
- 登录记住我功能实现
- 登录页面“记住我”的功能实现
- Javaweb实现登录界面“记住我”功能
- cookie实现登录页面记住我和自动登录功能
- cookie实现登录页面记住我和自动登录功能
- 登录时 记住我
- 自动登录、记住我(保存登陆状态)实现
- 实现登录界面的“记住我”功能 JAVA
- 简单实现网页登录框中的“记住我”
- jquery.cookie.js 实现 登录时 记住我
- 登录实现记住密码
- 登录实现记住密码
- 登录时的"记住我"
- Qml输入文本并自动滚动
- 关于Gazebo ROS Kobuki plugin:NaN in d1. step time:0.01的问题
- 二叉树遍历
- Spring MVC 框架基础
- 用Python求解拿鸡蛋问题
- ThinkPHP 3.2.2 实现持久登录 ( 记住我 )
- webstorm显示后缀为php文件时,html代码不高亮解决办法
- 技术性能领先,阿里云网络产品全面升级为企业级
- javascript中的严格模式
- three.js 04-09 之 LineBasicMaterial 材质
- Firefly超小型开源主板— —ROC-RK3328-CC
- 服务器虚拟化集群部署
- 如何将VCSA添加到微软域控环境,并且实现微软域账号登陆vCenter
- Java基础_四大引用(强引用、软引用、弱引用、虚引用)