ThinkPHP3.2.3 实现自动登录功能的方法

实现持久登录,即用户在登录时,勾选了"记住我"之后,无论是否关闭浏览器,只要不退出登录,在指定的时间内始终保持登录状态(缺点是在另一台电脑上登录过后,之前那台电脑就不能继续保持登录状态)。

首先,持久登陆使用 cookie 实现,但是 cookie 中不能保存用户密码这样重要的信息,即使加密过。解决方案是在用户登录表中新建3个字段identifier:第二身份标识,token:永久登录标识,timeout:永久登录超时时间。

 在用户勾选了"记住我"登录时,应该生成一个唯一的 identifier,一个唯一的 token,并且设置一个过期时间 timeout,把两个代表身份的值写入cookie,设置 cookie 过期时间为 timeout,例如:setcookie('auth',"$identifier:$token",$timeout); 同时把三个值插入数据表;当用户再一次访问网站时,首先判断 cookie 中是否含有 auth,如果含有,则去数据库中进行身份比对(identifier 和 token),比对成功时,把用户信息写入 session,同时用户保持登录状态。

代码:

LoginController.class.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/10/15
 * Time: 13:51
 */
namespace Home\Controller;
use Think\Controller;
class LoginController extends Controller{
    /**
     * thinkphp3.2.3  自动登录
     */
    public function index(){
        //判断是否永久登录
        checkLong();
        //已经登录则跳转至个人中心
        if(isset($_SESSION['username'])){
            $this->redirect('User/ucenter');
        }else{
            //判断是否存在cookie
            if(isset($_COOKIE['username'])){
               $this->assign('username',$_COOKIE['username']);
            }
            //显示注册页
            $this->display();
        }
    }
    //显示验证码
    public function verifyImg(){
        ob_clean();
        $Verify = new \Think\Verify();
        $Verify->fontSize = 18;
        $Verify->length   = 4;
        $Verify->codeSet = '0123456789';
        $Verify->entry();
    }
    //验证登录
    public function check(){
        header("Content-type:text/html;charset=utf-8");
        $verify = new \Think\Verify();
        $yzm = I("post.yzm",'trim');
        $username = I("post.username","trim");
        $password = I("post.password","trim");
        $remember = I("post.remember","trim");
        if($verify->check($yzm)){
            //判断用户名密码
            $user = new \Home\Model\UserModel();
            $res = $user->checkName($username,$password);
            if($res === false){
                $this->error("用户名或密码错误");
            }else{
                //用户信息存入session
                session("username",$res['username']);
                session("uid",$res['uid']);
                //如果用户勾选了"记住我",则保持持久登陆
                if($remember){
                    $salt = random_str(16);
                    //第二分身标识
                    $identifier = md5($salt . md5($username) . $salt);
                    //永久登录标识
                    $token = md5(uniqid(rand(), true));
                    //永久登录超时时间(1周)
                    $timeout = time()+60*2;
                    //存入cookie
                    cookie('auth',"$identifier:$token",$timeout);
                    $user->saveRemember($res['uid'],$identifier,$token,$timeout);
                }
                //把用户名存入cookie,退出登录后在表单保存用户名信息
                cookie('username',$username,time()+3600*24);
                //跳转至会员中心
                $this->redirect('Home/User/ucenter');
            }
        }else{
            $this->error("验证码不正确");
        }
    }
    //退出登录
    public function loginout(){
        session(null);
        cookie('auth', '', time()-1);
        $this->redirect("Login/index");
    }
    
}

UserController.class.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/10/15
 * Time: 13:59
 */
namespace Home\Controller;
class UserController extends CommonController{
    /**
     * 用户中心
     */
    public function ucenter(){
        //判断是否永久登录
        //$this->checkLong();
        $this->assign("session",$_SESSION);
        $this->display();
    }

}

CommonController.class.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/10/15
 * Time: 16:01
 */
namespace Home\Controller;
use Think\Controller;
class CommonController extends  Controller{
    public function _initialize(){
        //判断是否永久登录
        checkLong();
        //未登录
        if(!isset($_SESSION['username'])){
            //判断是否存在cookie
            if(isset($_COOKIE['username'])){
                $this->assign('username',$_COOKIE['username']);
            }
            $this->redirect('Login/index');
        }
    }

}

function.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/10/15
 * Time: 16:06
 */
//判断是否持久登录
function checkLong(){
    $check = new \Home\Model\UserModel();
    $is_long = $check->checkRemember();
    if($is_long === false){//token不对或者失效的状态
        cookie('auth', '', time()-1);
        session(null);
    }else{
        session("username",$is_long['username']);
        session("uid",$is_long['uid']);
    }
}
//生成随机数,用于生成salt
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;
}

UserModel.class.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/10/15
 * Time: 14:35
 */
namespace Home\Model;
use Think\Model;
class UserModel extends Model{
    //验证登录信息
    public function checkName($name,$pwd){
        $admin = M("user");
        $ini = array();
        $ini['username']  = $name;
        $salt    = 'user';
        $pwdword = md5($pwd.$salt);
        $info = $admin->where($ini)->find();
        if($info != null){
            //验证密码
            if($info['password'] == $pwdword){
                return $info;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }
    //当用户勾选"记住我"
    public function saveRemember($uid,$identifier,$token,$timeout){
        $admin = M("user");
        $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("user");
        $ini['identifier'] = $arr['identifier'];//
        $info = $admin->where($ini)->find();
        if($info != null){
            if($arr['token'] != $info['token']){
                return false;
            }else if($now > $info['timeout']){
                return false;
            }else{
                return $info;
            }
        }else{
            return false;
        }
    }


}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</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>个人中心</title>
        </head>
<body>
<if condition="$session['username'] neq null">
    <i>{$session.username},</i>
    <else />
    <i>游客,</i>
</if>
欢迎您<br>
<a href="{:U('Login/loginout')}">退出登录</a>
</body>
</html>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值