通过session_id限制仅一个用户登录
需求:
我们有的时候,希望一个账户,仅在一个地方登录。即,在别的地方登录该账户时,当前用户会被自动注销。
思路:
用户数据表admin
id | name | password | session_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
部署说明:
- host添加 127.0.0.1 login.com
- 在本地新建数据库test,新建表admin
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇: PHP提高SESSION响应速度的几种方法
- 下一篇: 解决crontab定时任务不能写入文件的问题