通过session_id限制仅一个用户登录

需求:

我们有的时候,希望一个账户,仅在一个地方登录。即,在别的地方登录该账户时,当前用户会被自动注销。

思路:

用户数据表admin

idnamepasswordsession_id
1 root 63a9f0ea7bb98050796b649e85481845 3olcdjkj5jjaq2u9t30mbuna96

我们实现该功能只需要在普通用户验证的基础上,加一层session_id的验证就可以了。我们在用户登录的时候,将此时的session_id写入数据表,session_id在本次session有效期是不会变化的。如果在别的地方,登录了该账户,则新的session_id值会写入数据表,则在验证用户信息的时候,当前用户的session_id和数据表里面的session_id不一致。

核心代码:

indexController.class.php

<?php

/**
 * Created by PhpStorm.
 * User: koastal
 * Date: 2016/5/15
 * Time: 19:28
 */
class indexController extends Controller
{
    function __construct()
    {
        parent::__construct();
    }

    /**
     * 显示用户信息页面
     */
    function index()
    {
        $loginController = new loginController();
        $loginController->isLogin();
        $this->smarty->assign("name",$_SESSION['name']);
        $this->smarty->assign("id",$_SESSION['id']);
        $this->smarty->display("info.html");
    }
}

loginController.class.php

<?php

/**
 * Created by PhpStorm.
 * User: koastal
 * Date: 2016/5/28
 * Time: 20:37
 */
class loginController extends Controller
{
    private $loginModel;
    function __construct()
    {
        parent::__construct();
        $this->loginModel = new loginModel();
    }

    /**
     * @return bool
     * 判断当前登录用户是否合法
     */
    function isLogin(){
        $res = $this->loginModel->getUserInfoById($_SESSION['id']);
        if(empty($res)){
            echo "未登录";exit;
        }else{
            $sql_token = md5($res['name'].$res['password']);
            if($sql_token != $_SESSION['token']){
                echo "用户验证失败";exit;
            }else{
                if(session_id()!=$res['session_id']){
                    echo "该账户已在别处登录";exit;
                }else{
                    return true;
                }
            }
        }
    }

    /**
     * 显示登录表单
     */
    function form(){
        $this->smarty->display("login.html");
    }

    /**
     * 执行登录操作
     */
    function action(){
        $name = $_POST['name'];
        $password = md5($_POST['password']);
        $session_id = session_id();
        $res = $this->loginModel->loginCheck($name,$password,$session_id);
        if($res){
            $_SESSION['id'] = $res['id'];
            $_SESSION['name'] = $name;
            $_SESSION['token'] = md5($name.$password);
            header("Location:http://login.com/index.php/index/index");
        }else{
            header("Location:http://login.com/index.php/login/form");
        }
    }
}

loginModel.class.php

<?php

/**
 * Created by PhpStorm.
 * User: koastal
 * Date: 2016/5/28
 * Time: 19:56
 */
class loginModel extends Model
{
    /**
     * @param $id
     * @return bool
     */
    function getUserInfoById($id){
        $sparam = array('id','name','password','session_id');
        $wparam = array("id[=]"=>$id);
        $data = $this->select("admin",$sparam,$wparam);
        if(empty($data)){
            return false;
        }else{
            return $data[0];
        }
    }
    /**
     * @param $name
     * @param $password
     * @param $session_id
     * @return array/bool
     */
    function loginCheck($name,$password,$session_id){
        $sparam = array('id','name','password',"session_id");
        $wparam = array("name[=]"=>$name);
        $data = $this->select("admin",$sparam,$wparam);
        if(empty($data)){
            return false;
        }else{
            $info = $data[0];
            if($info['password']!=$password){
                //验证失败
                return false;
            }else{
                //验证成功,更新session
                $newdata = ["session_id"=>$session_id];
                $wparam = ["id[=]"=>$info['id']];
                $this->update("admin",$newdata,$wparam);
                return $info;
            }
        }
    }
}

项目代码下载:

链接:http://pan.baidu.com/s/1kVAPJjp 密码:04iv

部署说明:

  1. host添加 127.0.0.1 login.com
  2. 在本地新建数据库test,新建表admin
posted @ 2017-11-07 10:53  袁浩浩  阅读(2661)  评论(0编辑  收藏  举报