欢迎来到福编程网,本站提供各种互联网专业知识!

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

发布时间:2016-05-16 作者:懒人 来源:转载
这篇文章主要介绍了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 TestController;
use ThinkController;
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 ThinkVerify();
  //$verify->useZh = true; //使用中文验证码
  $verify->length = 4; 
  $verify->entry();
 }
 //验证登录
 public function check(){
  $verify = new ThinkVerify();
  if($verify->check(I("yzm"))){
   //判断用户名密码
   $user = new TestModelTestModel();
   $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 = "ThinkVerify";
  //第三个参数为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 TestModelTestModel();
  $is_long = $check->checkRemember();
  if($is_long === false){
  }else{
   session("username",$is_long['uname']);
   session("id",$is_long['uid']);
  }
 }
}

模型 TestModel.class.php

<?php
namespace TestModel;
use ThinkModel;
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




 
 Document


视图 个人中心 ucenter.html




 
 Documenttitle>
</head>
<body>
 <if condition="$session['username'] neq null">
 <i>{$session.username},</i>
 <else />
 <i>游客,</i>
 </if>
 欢迎您</p><p>
 <a href="__CONTROLLER__/loginout">退出登录</a>
</body>
</html>

</pre>

<p><strong>附:模块目录</strong></p>
<p><img alt="" src="http://files.jb51.net/file_images/article/201605/201651690900929.jpg?20164169919" /></p>
<p><strong>补充:<span style="color: #ff6600">小编在这里推荐一款本站的php格式化美化的排版工具帮助大家在以后的PHP程序设计中进行代码排版:</span></p><p>
</strong></p>
<p><strong><span style="color: #0000ff">php代码在线格式化美化工具:</span></strong>http://tools.jb51.net/code/phpformat</p>
<p>更多关于thinkPHP相关内容感兴趣的读者可查看本站专题:《ThinkPHP入门教程》、《ThinkPHP常用方法总结》、《smarty模板入门基础教程》及《PHP模板技术总结》。</p>
<p>希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。</p></div>
                <div class="prev-next">
					<div class="prev">上一篇:<a href="/index.php/php/example/item-12405.html">php metaphone()函数的定义和用法</a></div><div class="next">下一篇:<a href="/index.php/php/example/item-12409.html">Yii2 GridView实现列表页直接修改数据的方法</a></div>
				</div>
						</div>
			<div class="qf-article-container">
				<div class="qf-cms-name">
					<h3>相关推荐</h3>
				</div>
				<div class="qf-cms-container">
					<ul class="article-list-relationship">
											<li><a href="/index.php/php/example/item-19251.html" title="PHP命令行执行整合pathinfo模拟定时任务实例" target="_blank">PHP命令行执行整合pathinfo模拟定时任务实例</a>
						</li>
											<li><a href="/index.php/php/example/item-19252.html" title="PHP url的pathinfo模式加载不同控制器的简单实现" target="_blank">PHP url的pathinfo模式加载不同控制器的简单实现</a>
						</li>
											<li><a href="/index.php/php/example/item-19253.html" title="py文件转exe时包含paramiko模块出错解决方法" target="_blank">py文件转exe时包含paramiko模块出错解决方法</a>
						</li>
											<li><a href="/index.php/php/example/item-19254.html" title="PHP 自动加载的简单实现(推荐)" target="_blank">PHP 自动加载的简单实现(推荐)</a>
						</li>
											<li><a href="/index.php/php/example/item-19255.html" title="php网页版聊天软件实现代码" target="_blank">php网页版聊天软件实现代码</a>
						</li>
											<li><a href="/index.php/php/example/item-19256.html" title="php+jquery+html实现点击不刷新加载更多的实例代码" target="_blank">php+jquery+html实现点击不刷新加载更多的实例代码</a>
						</li>
											<li><a href="/index.php/php/example/item-19257.html" title="PHP请求Socket接口测试实例" target="_blank">PHP请求Socket接口测试实例</a>
						</li>
											<li><a href="/index.php/php/example/item-19258.html" title="PHPWind9.0手动屏蔽验证码解决后台关闭验证码但是依然显示的问题" target="_blank">PHPWind9.0手动屏蔽验证码解决后台关闭验证码但是依然显示的问题</a>
						</li>
											<li><a href="/index.php/php/example/item-19259.html" title="PHP 读取大文件并显示的简单实例(推荐)" target="_blank">PHP 读取大文件并显示的简单实例(推荐)</a>
						</li>
											<li><a href="/index.php/php/example/item-19260.html" title="PHP Oauth授权和本地加密实现方法" target="_blank">PHP Oauth授权和本地加密实现方法</a>
						</li>
											<li><a href="/index.php/php/example/item-19261.html" title="Yii2.0中的COOKIE和SESSION用法" target="_blank">Yii2.0中的COOKIE和SESSION用法</a>
						</li>
											<li><a href="/index.php/php/example/item-19247.html" title="PHP实现四种基础排序算法的运行时间比较(推荐)" target="_blank">PHP实现四种基础排序算法的运行时间比较(推荐)</a>
						</li>
											<li><a href="/index.php/php/example/item-19236.html" title="PHP身份证校验码计算方法" target="_blank">PHP身份证校验码计算方法</a>
						</li>
											<li><a href="/index.php/php/example/item-19237.html" title="PHP通过加锁实现并发情况下抢码功能" target="_blank">PHP通过加锁实现并发情况下抢码功能</a>
						</li>
											<li><a href="/index.php/php/example/item-19239.html" title="Yii2的XSS攻击防范策略分析" target="_blank">Yii2的XSS攻击防范策略分析</a>
						</li>
											<li><a href="/index.php/php/example/item-19240.html" title="Yii2基于Ajax自动获取表单数据的方法" target="_blank">Yii2基于Ajax自动获取表单数据的方法</a>
						</li>
											<li><a href="/index.php/php/example/item-19241.html" title="Yii2实现上下联动下拉框功能的方法" target="_blank">Yii2实现上下联动下拉框功能的方法</a>
						</li>
											<li><a href="/index.php/php/example/item-19242.html" title="Yii2实现同时搜索多个字段的方法" target="_blank">Yii2实现同时搜索多个字段的方法</a>
						</li>
											<li><a href="/index.php/php/example/item-19243.html" title="Yii2实现让关联字段支持搜索功能的方法" target="_blank">Yii2实现让关联字段支持搜索功能的方法</a>
						</li>
											<li><a href="/index.php/php/example/item-19244.html" title="Yii2中关联查询简单用法示例" target="_blank">Yii2中关联查询简单用法示例</a>
						</li>
										</ul>
				</div>	
			</div>
		</div>
		<div class="sidebar">
			<div class="qf-cms-name">
				<h3>文章分类</h3>
			</div>
			<div class="qf-cms-container">
				<div class="qf-category-list">
									<a href="/index.php/php/basic/index.html" title="php基础" target="_blank">php基础</a>
									<a href="/index.php/php/skill/index.html" title="php技巧" target="_blank">php技巧</a>
									<a href="/index.php/php/example/index.html" title="php实例" target="_blank">php实例</a>
									<a href="/index.php/php/article/index.html" title="php文摘" target="_blank">php文摘</a>
									<a href="/index.php/php/template/index.html" title="php模板" target="_blank">php模板</a>
								</div>
			</div>
			<div class="qf-cms-name">
				<h3>热门关键词</h3>
			</div>
			<div class="qf-cms-container">
				<div class="qf-tag-list">
									<a href="https://zhannei.baidu.com/cse/site?q=雪佛兰&cc=fuphp.cn&ie=utf-8" title="雪佛兰" target="_blank">雪佛兰</a>
									<a href="https://zhannei.baidu.com/cse/site?q=通用&cc=fuphp.cn&ie=utf-8" title="通用" target="_blank">通用</a>
									<a href="https://zhannei.baidu.com/cse/site?q=奢华&cc=fuphp.cn&ie=utf-8" title="奢华" target="_blank">奢华</a>
									<a href="https://zhannei.baidu.com/cse/site?q=劳斯莱斯&cc=fuphp.cn&ie=utf-8" title="劳斯莱斯" target="_blank">劳斯莱斯</a>
									<a href="https://zhannei.baidu.com/cse/site?q=旗舰版&cc=fuphp.cn&ie=utf-8" title="旗舰版" target="_blank">旗舰版</a>
									<a href="https://zhannei.baidu.com/cse/site?q=64位&cc=fuphp.cn&ie=utf-8" title="64位" target="_blank">64位</a>
									<a href="https://zhannei.baidu.com/cse/site?q=收藏夹&cc=fuphp.cn&ie=utf-8" title="收藏夹" target="_blank">收藏夹</a>
									<a href="https://zhannei.baidu.com/cse/site?q=解调器&cc=fuphp.cn&ie=utf-8" title="解调器" target="_blank">解调器</a>
									<a href="https://zhannei.baidu.com/cse/site?q=网卡&cc=fuphp.cn&ie=utf-8" title="网卡" target="_blank">网卡</a>
									<a href="https://zhannei.baidu.com/cse/site?q=网线&cc=fuphp.cn&ie=utf-8" title="网线" target="_blank">网线</a>
									<a href="https://zhannei.baidu.com/cse/site?q=分辨率&cc=fuphp.cn&ie=utf-8" title="分辨率" target="_blank">分辨率</a>
									<a href="https://zhannei.baidu.com/cse/site?q=家电&cc=fuphp.cn&ie=utf-8" title="家电" target="_blank">家电</a>
									<a href="https://zhannei.baidu.com/cse/site?q=4k&cc=fuphp.cn&ie=utf-8" title="4k" target="_blank">4k</a>
									<a href="https://zhannei.baidu.com/cse/site?q=显示器&cc=fuphp.cn&ie=utf-8" title="显示器" target="_blank">显示器</a>
									<a href="https://zhannei.baidu.com/cse/site?q=header&cc=fuphp.cn&ie=utf-8" title="header" target="_blank">header</a>
									<a href="https://zhannei.baidu.com/cse/site?q=USER_AGENT&cc=fuphp.cn&ie=utf-8" title="USER_AGENT" target="_blank">USER_AGENT</a>
									<a href="https://zhannei.baidu.com/cse/site?q=色彩&cc=fuphp.cn&ie=utf-8" title="色彩" target="_blank">色彩</a>
									<a href="https://zhannei.baidu.com/cse/site?q=图形&cc=fuphp.cn&ie=utf-8" title="图形" target="_blank">图形</a>
									<a href="https://zhannei.baidu.com/cse/site?q=商业&cc=fuphp.cn&ie=utf-8" title="商业" target="_blank">商业</a>
									<a href="https://zhannei.baidu.com/cse/site?q=生成&cc=fuphp.cn&ie=utf-8" title="生成" target="_blank">生成</a>
					
				</div>
			</div>
			<!--广告 start-->
			<div class="qf-cms-name">
				<h3>热门文章</h3>
			</div>
			<div class="qf-cms-container">
				<ul class="qf-article-list">
													<li><em>1</em>
						<a href="/index.php/css/item-15931.html" title="html在线编辑器的更新[2006-05]" target="_blank">html在线编辑器的更新[2006-05]</a>
					</li>
									<li><em>2</em>
						<a href="/index.php/encryption/item-16144.html" title="PECompact.v1.80.b2解密详解" target="_blank">PECompact.v1.80.b2解密详解</a>
					</li>
									<li><em>3</em>
						<a href="/index.php/encryption/item-16146.html" title="DB2中的数据值加密" target="_blank">DB2中的数据值加密</a>
					</li>
									<li><em>4</em>
						<a href="/index.php/encryption/item-16148.html" title="密钥或对称密钥加密术" target="_blank">密钥或对称密钥加密术</a>
					</li>
									<li><em>5</em>
						<a href="/index.php/encryption/item-16150.html" title="教你怎样“藏”服务器的密码" target="_blank">教你怎样“藏”服务器的密码</a>
					</li>
									<li><em>6</em>
						<a href="/index.php/encryption/item-16152.html" title="破解40位MD5加密" target="_blank">破解40位MD5加密</a>
					</li>
									<li><em>7</em>
						<a href="/index.php/encryption/item-16154.html" title="DSA算法教程" target="_blank">DSA算法教程</a>
					</li>
									<li><em>8</em>
						<a href="/index.php/encryption/item-16156.html" title="自己制作硬件级别系统加密锁" target="_blank">自己制作硬件级别系统加密锁</a>
					</li>
									<li><em>9</em>
						<a href="/index.php/encryption/item-16158.html" title="演示从注册表中还原MSNMessenger口令" target="_blank">演示从注册表中还原MSNMessenger口令</a>
					</li>
									<li><em>10</em>
						<a href="/index.php/encryption/item-16160.html" title="ASP.NET中MD5和SHA1加密的几种方法" target="_blank">ASP.NET中MD5和SHA1加密的几种方法</a>
					</li>
								</ul>
			</div>
			<div class="qf-cms-name">
				<h3>最新更新</h3>
			</div>
			<div class="qf-cms-container">
				<ul class="qf-article-list">
													<li><a href="/index.php/changshi/item-79334.html" title="无线路由器经常断线 故障解决" target="_blank">无线路由器经常断线 故障解决</a>
					</li>
									<li><a href="/index.php/changshi/item-79351.html" title="怎么在Mac上设置锁屏不待机" target="_blank">怎么在Mac上设置锁屏不待机</a>
					</li>
									<li><a href="/index.php/changshi/item-79354.html" title="VHD和VHDX硬盘格式有什么区别?" target="_blank">VHD和VHDX硬盘格式有什么区别?</a>
					</li>
									<li><a href="/index.php/changshi/item-79363.html" title="关闭Aero Shake节约系统资源的方法" target="_blank">关闭Aero Shake节约系统资源的方法</a>
					</li>
									<li><a href="/index.php/changshi/item-79362.html" title="怎么更改Mac中的邮件字体大小" target="_blank">怎么更改Mac中的邮件字体大小</a>
					</li>
									<li><a href="/index.php/changshi/item-79371.html" title="提高WIN7系统开机速度方法分享" target="_blank">提高WIN7系统开机速度方法分享</a>
					</li>
									<li><a href="/index.php/changshi/item-79361.html" title="Mac系统怎么更改用户登录密码" target="_blank">Mac系统怎么更改用户登录密码</a>
					</li>
									<li><a href="/index.php/changshi/item-79358.html" title="Mac上如何修改时间和日期" target="_blank">Mac上如何修改时间和日期</a>
					</li>
									<li><a href="/index.php/changshi/item-79366.html" title="如何将常用应用固定至开始屏幕或任务栏" target="_blank">如何将常用应用固定至开始屏幕或任务栏</a>
					</li>
									<li><a href="/index.php/mysql/item-79372.html" title="MySQL中replace into语句的用法详解(insert into 的增强版)" target="_blank">MySQL中replace into语句的用法详解(insert into 的增强版)</a>
					</li>
								</ul>
			</div>
			<!--广告 start-->
			<div class="qf-ads qf-ads-ontop"><ul class="qf-ads-nUl-11"><li><a href="http://www.hnqfu.cn" target="_blank"><img src="/uploads/images/ads/202306/20230610081510415263.jpg"></a><a href="http://www.hnqfu.cn" target="_blank" class="alink"><label>广告</label><span>商业广告,理性选择</span></a></li></ul></div>
		</div>
	</div>
</div>

<script type="text/javascript">
var scrollPh = 1680;
layui.use('code', function(){
	layui.code({
		elem: 'pre',
		title: '代码',
		encode: false,
		ln: true,
		//skin: 'dark',
		//about: '123',
		about: [
			//'<a href="javascript:;">复制</a>'
		]
	});
});
</script>

<div class="wrap bottom">
	<div class="wrapper clearfix">
		<div class="links">
			<a href="http://www.scfxz.com">网站首页</a>
							 | <a href="/index.php/aboutus.html">关于我们</a>
							 | <a href="/index.php/wangzhanshengming.html">免责声明</a>
							 | <a href="/index.php/guanggaohezuo.html">广告合作</a>
							 | <a href="/index.php/contact.html">联系我们</a>
					</div>
		<div class="copyright">
			Copyright @ 2015-2026 <a href="" title="河南全福网络科技有限公司专业网制设计制作,PHP二次开发">福编程</a> All Rights Reserved.
		</div>
		<div class="copyright">
			<a href="http://beian.miit.gov.cn" target="_blank" rel="nofollow">豫ICP备15036959号-4</a>
		</div>
    </div>
</div>

<script type="text/javascript" src="//cpro.baidustatic.com/cpro/ui/cm.js" async="async" defer="defer" ></script>
<script type="text/javascript">
layui.config({
	base: '/static/js/layuiadmin/' //静态资源所在路径
}).extend({
	qf: '../qfplus/qf/qf',
	contact: '../qfplus/contact/contact',
}).use(['contact'], function(){
	var contact = layui.contact;
	contact.render({'position':	'left', 'oappend':'.qf-quick-bar'});
	//菜单
	jQuery(".submenu").slide({ 
		type:"menu",// 效果类型,针对菜单/导航而引入的参数(默认slide)
		titCell:".nLi", //鼠标触发对象
		targetCell:".sub", //titCell里面包含的要显示/消失的对象
		titOnClassName:'current',
		effect:"slideDown", //targetCell下拉效果
		delayTime:300 , //效果时间
		triggerTime:0, //鼠标延迟触发时间(默认150)
		returnDefault:true //鼠标移走后返回默认状态,例如默认频道是“预告片”,鼠标移走后会返回“预告片”(默认false)
	});
	//表单
	var form = layui.form;
	form.render(null, 'component-form');
	/* 监听提交 */
	form.on('submit(component-form-submit)', function(data){
		var searchkey = data.field.searchkey;
		return true;
	});
	//滚动固顶
	$(document).scroll(function(){
		var sTop = $(document).scrollTop();
		if( sTop >= scrollPh ){
			$('.qf-ads-ontop').css({'position':'fixed', 'top':'0'});
		}else{
			$('.qf-ads-ontop').css({'position':'relative'});
		}
	});
});
</script>
<script>
var _hmt = _hmt || [];
(function() {
	var hm = document.createElement("script");
	hm.src = "https://hm.baidu.com/hm.js?4a64b093e68b1f204f10a653c98b3264";
	var s = document.getElementsByTagName("script")[0]; 
	s.parentNode.insertBefore(hm, s);
})();
</script>

</body>
</html>