PHP实现同一个帐号不允许多人同时重复登陆

数据库表 user_login_info
字段:id,user_ip,user_id,last_access_time
user_id 做唯一性索引
1. 用户登录后
如果没有当前用户我的百分之一的数据,插入一条数据,user_ip(用户机器的IP),user_id(用户ID),last_access_time(当前登录时间)
如果已经存在,则更新 user_ip,last_access_time 2个字段
2. 如何判断?
另一个用户,如果用相同的账号
1)在同一台机器上再次登录的情况 【ip相同】,直接更新这个用户的 last_access_time 时间为最新时间就可以了。
处理:直接更新 shop.inernetwork.net last_access_time 为最新时间
2)在另外一台机器上登录的情况【ip不同】,根据user_id取出数据,判断ip和last_access_time(上次登录时间),
如果当前时间 now()-last_access_time < 10 (分钟) 【这里是关键,设置一个时间】,说明有人在其他机器上已经登录了,则不允许登录。
now()-last_access_time > 10 (分钟) ,则可以登录,说明另一个人要不已经有10分钟没有活动了,要不就是没登陆,这2种情况下都允许重新登录。
3. 在程序的入口文件 index.php (ZF框架参考),每次用户登录后的操作,都更新 last_access_time 时间为最新时间 (这个也许效率上需要考虑一下,其实也应该没什么问题,数据库完全可以承受,也可以在程序里加上一个判断,last_access_time 时间存在 session里,如果这个时间跟当前时间 date() 比较,超过设定的10分钟时间,则更新数据库 last_access_time 字段。这样可以减少更新数据库的次数)
4. 异常退出的情况,比如用户直接关闭浏览器,数据库里还有这条记录,因为设置的过期时间是10分钟,所以如果同一个用户立刻再次登录的情况下,肯定不行,会 提示已经有人登陆了。但10分钟后就可以再次登录,所以这个10分钟时间看具体情况,可以设置成 1分钟,或其他时间。
但这个时间不要设置成几个小时,那用户会疯掉。
原理:就是设置一个过期时间的技巧和记录IP。
一,会员表加一个字段(last_session),会员登陆时获取当前SESSIONID更新此字段。
二,会员登陆时取得该(last_session)值去session_save_path看该文件有没有,如有则直接删除。
三,假如有两个人以上同时使用的话,那么前一个的会话文件就会被后面的一个所删除,也就被逼下线了。
这样也就达到了每次只能一个帐号使用的目的了,虽然用户体验略差,但也算是较高效的方法了。

【问题描述】:同一用户在同一时间多次登录如果不能检测出来,是危险的。因为,你无法知道是否有其他用户在登录你的账户。如何禁止同一用户多次登录呢?
【解决方案】
(1) 每次登录,身份认证成功后,重新产生一个session_id。

session_regenerate_id();
session_register ("username") ;

(2) 在用户数据库中开一个sessionid字段,重新产生session_id后,都更新该字段。

$sessionid = session_id();
$db = new PDO('sqlite:softToken.db');
$sql = "update userinfo set sessionid ='$sessionid' where username='$username' and passwd='$passwd';";
$query = $db->prepare($sql);
$query->execute();

(3) 建立一个session保存用户名

$_SESSION["username"] = $username;

(4) 利用url重写,传递session_id

$url = "main.php?sid=".session_id();
unset($db);
echo "<font color=blue>登录成功,正在跳转!</font>" ;
header ("Location:$url");

(5) 在需要跳转的页面,起始处加入
main.php

<?php
header('Content-type:text/html; charset=utf-8');
$sessionid = $_GET['sid'];
session_id($sessionid);
session_start ();
$username = $_SESSION["username"];
$db = new PDO('sqlite:softToken.db');
$sql = "select * from userinfo where username='$username' and sessionid='$sessionid';";
$query = $db->prepare($sql);
$query->execute();
$user = $query->fetch(PDO::FETCH_OBJ);
if ($user->username == ""){
session_destroy();
echo "<script language='javascript' type='text/javascript'>" ;
echo "window.location.href = 'index.html';" ;
echo "</script>" ;
exit () ;
}
?>
<html>
<body>
......
</body>
</html>

以上就是php有效防止同一账号同一时间多次登录的解决方案,希望对大家解决同一账号同一时间多次登录问题有所帮助。

php有效防止同一用户多次登录的更多相关文章

  1. Ansible-Tower快速入门-4.以超级用户帐号登录【翻译】

    以超级用户帐号登录 首先,登录tower需要使用tower服务器所在的URL,格式如下:https://<tower server name>/ 注意:tower安装了一个自签名证书用于H ...

  2. Mysql创建新用户后无法登录,提示 Access denied for user 'username'@'localhost' (using password: YES)

    MySQL创建新用户后无法登录,提示 Access denied for user 'username'@'localhost' (using password: YES) ,多半是因为存在匿名用户, ...

  3. php实现单个用户禁止重复登录,防止同一用户同时登陆

    <?php session_start(); //ini_set('session.auto_start', 0); //关闭session自动启动 //ini_set('session.coo ...

  4. "SQLServer无法打开用户默认数据库,登录失败,错误4064"的解决办法

    "SQLServer无法打开用户默认数据库,登录失败,错误4064"的解决办法 1.检查登录密码 如果密码错误,修改数据库密码,用windows身份验证登录进去, (1)安全--登 ...

  5. ECSHOP手机号码或邮箱用户名都可以登录方法

    ECSHOP手机号码或邮箱用户名都可以登录方法 ECSHOP教程/ ecshop教程网(www.ecshop119.com) 2013-06-30   有不少人都在找支持ECShop用户名.邮箱或手号 ...

  6. 通过SessionID和用户名来保证同一个用户不能同时登录(单点登录)

    可以通过SessionID和用户名来保证同一个用户不能同时登录的问题,下面程序模仿了QQ的登录,当登录后判断当前帐号是否已经登录,如果登录.则踢掉以前登录的用户. 1.通过Application全局变 ...

  7. mysql新建用户本地无法登录

    mysql新建用户本地无法登录 MySQLDebianGoogleAccess  出此是用mysql,因为root权限过高,所以新建一用户appadmin,权限仅为要用到的数据库.创建语句如下:gra ...

  8. [ionic开源项目教程] - 第15讲 ionic用户个人中心登录注册的实现

    第15讲 ionic用户个人中心登录注册的实现 这一讲包括登陆.注册.个人中心.个人资料页面的实现. 在一讲的改动有四个地方: 在config.js里配置接口地址 完善个人中心的服务层(service ...

  9. linux系统禁止root用户通过ssh登录及ssh的访问控制

    Linux系统默认情况下,是可以通过ssh以root权限登录的.但出于安全考虑,这样的权限是不合适的,因为黑客可能通过暴力破解你的root密码,然后进入你的系统,oh,damn it..... 同样是 ...

  10. .NET 统一用户管理 -- 单点登录

    单点登录 前言 本篇做为.Net 统一用户管理的系列文章的开山之作,主要说一个单点登录是怎么实现的,以及为啥要统一用户管理. 单点登录(Single Sign On),简称为 SSO,是目前比较流行的 ...

随机推荐

  1. Boost--optional

    #include <vector> #include <deque> #include <iostream> #include <array> #inc ...

  2. bzoj4814: [Cqoi2017]小Q的草稿

    Description 小Q是个程序员.众所周知,程序员在写程序的时候经常需要草稿纸.小Q现在需要一张草稿纸用来画图,但是桌上 只有一张草稿纸,而且是一张被用过很多次的草稿纸.草稿纸可以看作一个二维平 ...

  3. PAT 甲级 1011 World Cup Betting (20)(20 分)

    1011 World Cup Betting (20)(20 分)提问 With the 2010 FIFA World Cup running, football fans the world ov ...

  4. ArcMap VBA实现连续编号

    连续编号VBA部分:Static lCount as longlCount=lCount+1赋值部分:lCount (从1开始)lCount-1 (从0开始)

  5. web项目中添加MySQL驱动

    1.我这里采用yml文件来配置,yml有配置层次清晰,方便操作的好处: 将application.properties后缀改成yml,即配置文件变成application.yml 我的applicat ...

  6. WebSocket 跨域

    http://www.cnblogs.com/joeymary/p/5259464.html

  7. 图片Alpha预乘的作用[转]

    Premultiplied Alpha 这个概念做游戏开发的人都不会不知道.Xcode 的工程选项里有一项 Compress PNG Files,会对 PNG 进行 Premultiplied Alp ...

  8. Docker的常用命令

    docker命令有很多,总的分为以下几大类: 容器生命周期管理 — docker [run|start|stop|restart|kill|rm|pause|unpause] 容器操作运维 — doc ...

  9. Android获取文件夹下的所有子文件名称;

    public static List<String> getFilesAllName(String path) { File file=new File(path); File[] fil ...

  10. 在oracle中创建自动增长字段

    参考http://www.cnblogs.com/jerrmy/archive/2013/03/13/2958352.html http://www.jb51.net/article/43382.ht ...