ThinkPHP3.2.2實(shí)現(xiàn)持久登錄(記住我)功能的方法
本文實(shí)例講述了ThinkPHP3.2.2實(shí)現(xiàn)持久登錄功能的方法。分享給大家供大家參考,具體如下:
實(shí)現(xiàn)持久登錄,即用戶在登錄時(shí),勾選了"記住我"之后,無(wú)論是否關(guān)閉瀏覽器,只要不退出登錄,在指定的時(shí)間內(nèi)始終保持登錄狀態(tài)(缺點(diǎn)是在另一臺(tái)電腦上登錄過(guò)后,之前那臺(tái)電腦就不能繼續(xù)保持登錄狀態(tài))。
首先,持久登陸使用 cookie 實(shí)現(xiàn),但是 cookie 中不能保存用戶密碼這樣重要的信息,即使加密過(guò)。解決方案是在用戶登錄表中新建3個(gè)字段identifier:第二身份標(biāo)識(shí),token:永久登錄標(biāo)識(shí),timeout:永久登錄超時(shí)時(shí)間。
+------------+-------------+------+-----+---------+----------------+ | 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 | | +------------+-------------+------+-----+---------+----------------+
在用戶勾選了"記住我"登錄時(shí),應(yīng)該生成一個(gè)唯一的 identifier,一個(gè)唯一的 token,并且設(shè)置一個(gè)過(guò)期時(shí)間 timeout,把兩個(gè)代表身份的值寫入cookie,設(shè)置 cookie 過(guò)期時(shí)間為 timeout,例如:setcookie('auth',"$identifier:$token",$timeout); 同時(shí)把三個(gè)值插入數(shù)據(jù)表;當(dāng)用戶再一次訪問(wèn)網(wǎng)站時(shí),首先判斷 cookie 中是否含有 auth,如果含有,則去數(shù)據(jù)庫(kù)中進(jìn)行身份比對(duì)(identifier 和 token),比對(duì)成功時(shí),把用戶信息寫入 session,同時(shí)用戶保持登錄狀態(tài)。
代碼:
控制器 TestController.class.php
<?php
namespace Test\Controller;
use Think\Controller;
class TestController extends Controller {
public function login(){
//判斷是否永久登錄
$this->checkLong();
//已經(jīng)登錄則跳轉(zhuǎn)至個(gè)人中心
if(isset($_SESSION['username'])){
$this->redirect('Test/ucenter');
}else{
//判斷是否存在cookie
if(isset($_COOKIE['username'])){
$this->assign('username',$_COOKIE['username']);
}
//顯示注冊(cè)頁(yè)
$this->display("test");
}
}
//顯示驗(yàn)證碼
public function verifyImg(){
$verify = new \Think\Verify();
//$verify->useZh = true; //使用中文驗(yàn)證碼
$verify->length = 4;
$verify->entry();
}
//驗(yàn)證登錄
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 "用戶名或密碼錯(cuò)誤";
}else{
//用戶信息存入session
session("username",$res['uname']);
session("id",$res['uid']);
//如果用戶勾選了"記住我",則保持持久登陸
if(I("remember")){
$salt = $this->random_str(16);
//第二分身標(biāo)識(shí)
$identifier = md5($salt . md5(I("username") . $salt));
//永久登錄標(biāo)識(shí)
$token = md5(uniqid(rand(), true));
//永久登錄超時(shí)時(shí)間(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);
//跳轉(zhuǎn)至?xí)T中心
$this->redirect('Test/ucenter');
}
}else{
echo "輸入錯(cuò)誤";
}
}
//測(cè)試strstr函數(shù)
public function strstrtest(){
$param = "Think\Verify";
//第三個(gè)參數(shù)為true,返回'Think';沒(méi)有第三個(gè)參數(shù),返回'\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");
}
//生成隨機(jī)數(shù),用于生成salt
public function random_str($length){
//生成一個(gè)包含 大寫英文字母, 小寫英文字母, 數(shù)字 的數(shù)組
$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{
//驗(yàn)證登錄信息
public function checkName($name,$pwd){
$admin = M("admin");
$info = $admin->getByUname($name);
if($info != null){
//驗(yàn)證密碼
if($info['upwd'] == $pwd){
return $info;
}else{
return false;
}
}else{
return false;
}
}
//當(dāng)用戶勾選"記住我"
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;
}
//驗(yàn)證用戶是否永久登錄(記住我)
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;
}
}
}
視圖 登錄頁(yè) 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="驗(yàn)證碼"><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>
視圖 個(gè)人中心 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>
附:模塊目錄

補(bǔ)充:小編在這里推薦一款本站的php格式化美化的排版工具幫助大家在以后的PHP程序設(shè)計(jì)中進(jìn)行代碼排版:
php代碼在線格式化美化工具:http://tools.jb51.net/code/phpformat
更多關(guān)于thinkPHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《ThinkPHP入門教程》、《ThinkPHP常用方法總結(jié)》、《smarty模板入門基礎(chǔ)教程》及《PHP模板技術(shù)總結(jié)》。
希望本文所述對(duì)大家基于ThinkPHP框架的PHP程序設(shè)計(jì)有所幫助。
- thinkphp3.2實(shí)現(xiàn)跨控制器調(diào)用其他模塊的方法
- thinkphp3.2.3版本的數(shù)據(jù)庫(kù)增刪改查實(shí)現(xiàn)代碼
- Thinkphp3.2.3整合phpqrcode生成帶logo的二維碼
- thinkPHP3.2簡(jiǎn)單實(shí)現(xiàn)文件上傳的方法
- thinkphp3.2框架中where條件查詢用法總結(jié)
- ThinkPHP3.1之D方法實(shí)例詳解
- ThinkPHP3.2.3框架實(shí)現(xiàn)執(zhí)行原生SQL語(yǔ)句的方法示例
- ThinkPHP3.2.3所有的單字母方法整理總結(jié)
相關(guān)文章
php使用正則驗(yàn)證密碼字段的復(fù)雜強(qiáng)度原理詳細(xì)講解
密碼涉及到安全問(wèn)題,所以密碼設(shè)計(jì)的復(fù)雜程序尤為重要。通常密碼由大小寫字母、數(shù)字、特殊符號(hào)組成。一般情況下前端可不做js判斷,使用ajax提交php后端程序接口,由后端判斷后返回json數(shù)據(jù),進(jìn)行用戶密碼復(fù)雜程序提示。2022-11-11
ThinkPHP模板判斷輸出Empty標(biāo)簽用法詳解
這篇文章主要介紹了ThinkPHP模板判斷輸出Empty標(biāo)簽用法,需要的朋友可以參考下2014-06-06
ThinkPHP中__initialize()和類的構(gòu)造函數(shù)__construct()用法分析
這篇文章主要介紹了ThinkPHP中__initialize()和類的構(gòu)造函數(shù)__construct()用法,以實(shí)例形式分析了ThinkPHP中類的初始化時(shí)構(gòu)造子類的方法,是采用ThinkPHP進(jìn)行面向?qū)ο蟪绦蛟O(shè)計(jì)中比較重要的概念,需要的朋友可以參考下2014-11-11
php實(shí)現(xiàn)統(tǒng)計(jì)IP數(shù)及在線人數(shù)的示例代碼
這篇文章主要介紹了php實(shí)現(xiàn)統(tǒng)計(jì)IP數(shù)及在線人數(shù)的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07

