php同一个用户同时只能登陆一个, 后登陆者踢掉前登陆者(排他登陆)
通常用户登陆,如果没有特别的限定, 同一个用户可以同时登陆, 今天搞了一个东西限定一个用户不能同时登陆到一个系统上, 后登陆者会把前面登陆的踢出来.(有点像QQ,同个帐号不能在多个地方同时在线, 后面登陆成功后就把前面登陆的掉线)
SQL : 两张表,一张是用户信息,另一张用来保存session
--
-- 数据库: `single_user`
--
CREATE TABLE IF NOT EXISTS `session` (
`username` varchar(50) default '',
`time` varchar(14) default '',
`session_id` varchar(200) NOT NULL default '0',
`userid` int(11) default '0',
PRIMARY KEY (`session_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `users` (
`userid` int(11) NOT NULL auto_increment,
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
PRIMARY KEY (`userid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
数据表 session 以session_id 为主键, 这个主键是 userid + user name + user login time 的 md5值算出来的. 每次用户登陆的时候就会像session表里插入一条,同时以userid username为条件查询旧的session记录并且删除他,所以当页面判断当前用户是否有效时,是通过$_SESSION数组里面保存在session_id值和数据库里取出来的session_id进行比较, 旧的session_id 在此用户第2次登陆时已经被删除,因此找不到,从而被退出系统.
代码部分
1.config.php 一些简单的配置,包括数据库的连接
<?php
$live_site = 'testing';
$session_life = 600;
function getConnect()
{
$db_local = 'localhost';
$db_user = 'root';
$db_pwd = 'root';
$db_name = 'single_userlogin'; $db_link = mysqli_connect($db_local, $db_user, $db_pwd,$db_name); if ($db_link)
{
return $db_link;
}
return false;
}
2. index.php 登陆页面
<?php
require_once('config.php');
$db = getConnect();
if (isset($_POST['username']) && isset($_POST['password']))
{
//处理用户登陆后的数据验证
$query = 'SELECT * FROM `users` WHERE `username`="' . trim($_POST['username']) . '" AND `password`="' .md5( trim( $_POST['password'] ) ) . '"';
$result = mysqli_query($db,$query); $rs_num = mysqli_num_rows($result); if ($rs_num > 0 )
{
//该用户存在
$row = mysqli_fetch_assoc($result);
$userid = $row['userid'];
$username = $row['username'];
$logintime = time(); //创建session_id值
$session_id = md5( $userid . $username . $logintime ); //登陆成功后要插入一条记录到session表中
$sql = 'INSERT INTO session SET `time`="'.$logintime.'", `session_id`="'.$session_id.'", `userid`='.$userid.', `username`="'.$username.'"';
mysqli_query( $db, $sql);
echo $sql; echo "<br>";
//并且要把session表里旧的session_id删除掉
$query = 'DELETE FROM `session` WHERE `userid`=' . $userid . ' AND `username`="' . $username . '" AND `session_id`!="' . $session_id . '"';
$old_session = mysqli_query($db,$query);
echo $query; //开启session, 把新登陆的用户信息进入$_SESSION中
session_name( md5( $live_site ) );
session_id( $session_id );
session_start(); $_SESSION['session_id'] = $session_id;
$_SESSION['userid'] = $row['userid'];
$_SESSION['username'] = $row['username'];
$_SESSION['logintime'] = $logintime;
echo '<pre>';
var_dump($_SESSION);
session_write_close();
echo '<script type="text/javascript">window.location.href="index2.php"</script>';
} else {
echo '<script type="text/javascript">window.location.href="index.php?mosmsg=Username Error"</script>';
}
} else {
//用户登陆框
?>
<form method="post" name="user_login" id="user_login" action="index.php">
Username:<input type="text" name="username" id="username" value=""/>
<br />
password:<input type="password" name="password" id="password" value=""/>
<br />
<input type="submit" name="submit" id="submit" value="Submit"/>
</form>
<?php
}
?>
3. index2.php 用户成功登陆后需要处理原来上一次该用户的session信息, 如果上一次此用户的登陆信息还有效,需要将其删除
<?php
require_once('config.php');
$db = getConnect();
session_name( md5( $live_site ) );
session_start(); $userid = $_SESSION['userid'];
$username = $_SESSION['username'];
$logintime = $_SESSION['logintime'];
$session_id = $_SESSION['session_id']; //判断用户是否有登陆
if ($session_id != session_id()) {
echo "<script>document.location.href='index.php?mosmsg=Invalid Session'</script>\n";
exit();
}
if ($session_id == md5( $userid . $username . $logintime )) {
$past = time() - $session_life; //删除已经超时但是记录还存在的记录
$query = "DELETE FROM session"
. "\n WHERE time < '" . (int) $past . "'"
. "\n AND userid <> 0"
;
mysqli_query($db,$query);
$current_time = time();
// update session timestamp 更新登陆用户的时间戳
$query = 'UPDATE #__session'
. '\n SET time="' . $current_time . '"'
. '\n WHERE session_id = "' . $session_id . '"'; //以当前用户登陆后产生的$session_id 来查询 session表里的记录是否存在
//如果不存在那么就跳到登陆页面
$query = "SELECT COUNT( session_id )"
. "\n FROM session"
. "\n WHERE session_id = '" . $session_id . "'"
. "\n AND username = '". $username . "'"
. "\n AND userid = ". $userid;
$session_rs = mysqli_query($db,$query);
$session_row = mysqli_fetch_row($session_rs);
$session_num = $session_row[0];
if ($session_num > 0 )
{
echo 'WELCOME<br / ><a href="logout.php">Logout</a>';
} else {
echo "<script>document.location.href='index.php?mosmsg=Admin Session Expired'</script>\n";
}
} else {
// session id does not correspond to required session format
echo "<script>document.location.href='index.php?mosmsg=Invalid Session'</script>\n";
exit();
}
?>
4. logout.php 退出用户,并且删除 SESSION
<?php
require_once('config.php');
$db = getConnect();
session_name( md5( $live_site ) );
session_start(); $userid = $_SESSION['userid'];
$username = $_SESSION['username'];
$logintime = $_SESSION['logintime'];
$session_id = $_SESSION['session_id']; $sql = 'DELETE FROM session WHERE userid='.$userid.' AND username="'.$username.'" AND session_id = "'.$session_id.'"';
mysqli_query($db,$sql);
session_destroy();
echo "<script>document.location.href='index.php'</script>\n";
exit();
?>
转载:https://www.cnblogs.com/belie8/articles/2196529.html
php同一个用户同时只能登陆一个, 后登陆者踢掉前登陆者(排他登陆)的更多相关文章
- 同一个PC只能运行一个应用实例(考虑多个用户会话情况)
原文:同一个PC只能运行一个应用实例(考虑多个用户会话情况) class Program { private static Mutex m; [STAThread] static void Main( ...
- (26)基于cookie的登陆认证(写入cookie、删除cookie、登陆后所有域下的网页都可访问、登陆成功跳转至用户开始访问的页面、使用装饰器完成所有页面的登陆认证)
获取cookie request.COOKIES['key'] request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age ...
- J2EE用监听器实现同一用户只能有一个在线
这里我们讨论的是已登陆或将要登陆的用户,游客不在讨论的范围之内.这一点大家应该很容易就能理解的吧. 那么我们应该怎样去实现同一用户只能有一个在线这样的一个小功能呢? 有人 ...
- 怎么取消 Windows Server 2012 r2 RDP 限制每个用户只能进行一个会话(转)
在 Windows Server 2008 / 2008 R2 上,如果希望多个远程用户使用同一个账号同时访问服务器的 Remote Desktop(RDP),只需通过管理工具-远程桌面下的“远程桌面 ...
- 怎么取消 Windows Server 2012 RDP 限制每个用户只能进行一个会话
在 Windows Server 2008 / 2008 R2 上,如果希望多个远程用户使用同一个账号同时访问服务器的 Remote Desktop(RDP),只需通过管理工具-远程桌面下的“远程桌面 ...
- jfinal+H5的websocket 实现同一账户在不同地点不同电脑只能登陆一个(互相踢下线)
jfinal+H5的websocket 实现同一账户在不同地点不同电脑只能登陆一个(互相踢下线):https://blog.csdn.net/liuyifeng1920/article/details ...
- 解决微信授权回调页面域名只能设置一个的问题 [php]
最终的解决方案是:https://github.com/liuyunzhuge/php_weixin_proxy,详细的介绍请往下阅读. 在做项目集成微信登录以及微信支付的时候,都需要进行用户授权.这 ...
- 通过SessionID和用户名来保证同一个用户不能同时登录(单点登录)
可以通过SessionID和用户名来保证同一个用户不能同时登录的问题,下面程序模仿了QQ的登录,当登录后判断当前帐号是否已经登录,如果登录.则踢掉以前登录的用户. 1.通过Application全局变 ...
- [asp.net mvc 奇淫巧技] 06 - 也许你的项目同一个用户的请求都是同步的
一.感慨 很久前看到一篇博客中有句话大致的意思是:“asp.net 程序性能低下的主要原因是开发人员技术参差不齐”,当时看到这句话不以为然,然而时间过的越久接触的.net 开发人员越多就越认同这句话: ...
随机推荐
- HDU 5773 The All-purpose Zero 脑洞LIS
给定一个序列,里面的0是可以任变的.问变化后最长的LIS的长度 首先,0全部选上是不亏的.这个不知道怎么说,YY一下吧. 最关键的就是解决2 0 0 3 这种问题了. 注意到这个序列的LIS应该是3 ...
- nginx 添加https支持
自行颁发不受浏览器信任的SSL证书为晒晒IQ网颁发证书.ssh登陆到服务器上,终端输入以下命令,使用openssl生成RSA密钥及证书. # 生成一个RSA密钥 $ openssl genrsa -d ...
- Vue打包后页面出现cannot get
学习Vue有大半个月了,然而遇到了不少坑,完全没有高手们那么容易,中间有不少值得记录下的东东,回头好好理理.先理下今天的: Vue打包命令简单啊,直接在命令行输入:npm run build 然而没一 ...
- JSP对象和JavaBean
1. JSP 客户端请求 当浏览器请求一个网页时,它会向网络服务器发送一系列不能被直接读取的信息,因为这些信息是作为HTTP信息头的一部分来传送的,如下图所示: Http请求头对应的内容如下: 对应方 ...
- 关于com工程依赖的一些总结
作者:朱金灿 来源:http://blog.csdn.net/clever101 一是com组件工程的依赖设置.比如A这个组件工程要使用B组件工程的类,要如何设置呢?具体就是先把在A工程里加上B工程的 ...
- 【转】【C++】【MFC】关于RADIO BUTTON的使用方法
*原文地址:http://blog.csdn.net/c_cyoxi/article/details/23868979 1. 环境:VS2010 2. 分组 将radio1.radio2.radio3 ...
- uvm_tlm——TLM1事务级建模方法(一)
TLM(事务级建模方法,Transaction-level modeling)是一种高级的数字系统模型化方法,它将模型间的通信细节与函数单元或通信架构的细节分离开来.通信机制(如总线或者FIFO)被建 ...
- 制作centos安装u盘
格式化 mkfs.vfat /dev/sdb1 制作 dd if=CentOS-7-x86_64-Minimal-1503-01.iso of=/dev/sdb # 1. 注意是/dev/sdb 不是 ...
- COGS 11. 运输问题1
★★☆ 输入文件:maxflowa.in 输出文件:maxflowa.out 简单对比时间限制:1 s 内存限制:128 MB [问题描述] 一个工厂每天生产若干商品,需运输到 ...
- 远程链接mongoDB robomongo
墙裂推荐一个软件robomongo 下载地址:https://robomongo.org/download 最初不用这个软件的时候需要shell链接mongoDB,折腾了半天结果版本不匹配 用robo ...