`
duinibuhaome
  • 浏览: 41471 次
  • 性别: Icon_minigender_1
  • 来自: 太原
社区版块
存档分类
最新评论

有关于同一时间用户只能在一个地方登录的问题

阅读更多

有关于同一时间用户只能在一个地方登录的问题

以下内容可能将的有点罗嗦,思路或者不清晰,请各位高手手下留情,肯定有更好的方法了,各位高手如果有的话,可否分享一下,谢谢!

 

1.在服务器,用户每次登录session都不一致,但是session内容中的登录信息或许一致,但是这里还存在一个时间差,如何判断同一个用户在别的地方登录呢

可以比对时间,根据时间大小来判断,当然时间大的就需要留下来了,小的自然就需要删除了

这时候又出现一个问题,你如何知道服务器session中那些session是同一个用户的呢,所以自然需要保持同一个用户的session在服务器最好是唯一.

首先需要有个地方保存session,不管你登录几次,都可以保存在这里,这里只是说的登录,如果要做其他操作,那么最后登录的肯定是没问题的,但是其他登录的就会提示此用户已在其他地方登录

 

现在说说保存session的地方,我使用的是hashmap<用户名,hashmap<时间,session>>,但是使用时间比较复杂,可以简化一下,使用用户登录次数,这个数值也是处于一直变大的情况中.那么保存的数据就变成hashmap<用户名,hashmap<登录次数,session>>

 

那么现在假设一下存session的地方也是hashmap,假设为A

那么同一个用户第一次登录都会发生

HashMap b=new HashMap();

B.put(1,session对象);

A.put(admin,b)

第二次登录

HashMap b=new HashMap();

B.put(2,session对象);

A.put(admin,b)

第三次登录

HashMap b=new HashMap();

B.put(3,session对象);

A.put(admin,b)

现在用户admin在不同的地方登录了三次。

按我们的需求来说,前两次在有其他操作就会提示此用户已在其他地方登录

当然第一次的登录和第二次的登录后的操作完全是独立开来的,就是说第一次登录和第二次登录后再有其他操作都会提示此用户已在其他地方登录,不分顺序先后,而第三次就没有影响啦,因为第三次是最后登录的,当然不会有影响的.

 

现在该说说如何让第一次和第二次登录后的操作提示此用户已在其他地方登录

首先该有拦截器,拦截器中怎么判断呢,肯定是根据用户名来判断了,因为我们存session的地方就是用用户名当做标示来存的,如果有,是不是该将这个session删除掉呢,删除掉以后提示

此用户已在其他地方登录,页面刷新,是不是页面就再次处于未登陆的情况呢.

 

比较简单吧,我在当时做的时候下了功夫不少,主要是怎么保存session,session里保存什么,经过几次考虑以及不少的测试才决定先将session和登陆次数保存在hashmap,在将hashmap和用户名保存在hashmap,肯定还有其他办法的.

 

下面说说怎么比较hashmap中的数据吧

上面已经说过 A(保存用户名和hashmap b的地方)

如果当前登陆用户如果在A不存在,那么需要添加

如果存在,那么是不是该比较里面的hashmap了呢

这里还有一个问题,只有一个用户登录的时候,也会经过过滤器,那么需要当前用户名在A中的数量必须大于1

大于一就要开始循环了,这里的时候就发现怎么循环呢,我使用迭代和while比较合适,

首先你需要全部将A中某用户的信息循环一遍,根据当前操作的sessionidB(B是保存在Ahashmap)是否一致,一致的话将B中的key取出来,也就是我们存在的登录次数.

 

在一次循环是不是该判断取出的keyB中的可以比大小了,取出的key必须是小于B中存放的key,才能够删除的,这里不需要标示一下,如果小于,立马停止循环,

 

第三次开始对比了,上面已经标示了是否小于B中的key,如果标示成立,那么循环中就需要比较一致的key,找到了就可以删除了,当然删除了自己,同时要将session清除掉,这样是不是就可以了呢.

 

以下是部分代码

获取登录次数

int dates=webUserManager.get_login_num(result.get("CH").toString());

 

MySessionMapClass.replaceSession(request.getSession(),result.get("CH").toString(),dates);

 

 

比对类

public class MySessionMapClass {

private static Map onlineSessionMap = new HashMap();// 已登录的会话列表

public static boolean replaceSession(HttpSession newSession, String kskh,int dates) {

boolean flag = false;

if (onlineSessionMap.containsKey(kskh)) {

//获取ch对应的hashmap

HashMap newHms=(HashMap)onlineSessionMap.get(kskh);

newHms.put(dates,newSession);

onlineSessionMap.put(kskh, newHms);

flag = true;

else {

// 如果会话列表中不包含该会话,则添加

HashMap hms=new HashMap();

hms.put(dates,newSession);

onlineSessionMap.put(kskh, hms);

flag = false;

}

return flag;

}

 

/**

 * 比较新会话和旧会话的ID,如果ID相同,则表示是同一个用户,返回true

 * 

 * @param session

 * @param kskh

 * @return boolean ID相同返回true,

 */

public static boolean isSameSession(HttpSession newSession, String kskh) {

boolean flag = false;

HashMap maps = new HashMap();

try {

// 获得旧会话

maps = (HashMap) onlineSessionMap.get(kskh);

if(maps!=null){

if(maps.size()>1){

//因为MAP中存储的键是日期时间字符串 值是session对象  留下最大的日期字符串  删除其他的session

String dates="";

//找出session对应的日期字符串

Iterator it = maps.entrySet().iterator();

while(it.hasNext()){

java.util.Map.Entry entry = (java.util.Map.Entry)it.next();

String keys= entry.getKey().toString();// 返回与此项对应的键

HttpSession values= (HttpSession)entry.getValue(); //返回与此项对应的值

if(newSession.getId().equals(values.getId())){

dates=keys;

}

}

Iterator it1 = maps.entrySet().iterator();

while(it1.hasNext()){

java.util.Map.Entry entry = (java.util.Map.Entry)it1.next();

String keys= entry.getKey().toString();// 返回与此项对应的键

HttpSession values= (HttpSession)entry.getValue(); //返回与此项对应的值

if(Integer.parseInt(dates)<Integer.parseInt(keys)){

flag=true;

break;

}else{

}

}

Iterator it2 = maps.entrySet().iterator();

while(it2.hasNext()){

java.util.Map.Entry entry = (java.util.Map.Entry)it2.next();

String keys= entry.getKey().toString();// 返回与此项对应的键

HttpSession values= (HttpSession)entry.getValue(); //返回与此项对应的值

if(flag==true){//删除自己

if(dates.equals(keys)){

maps.remove(keys);

values.invalidate();

}

}else{//删除别人

//if(!dates.equals(values)){

//maps.remove(keys);

//values.invalidate();

//}

}

}

}else{

flag=false;

}

}

catch (Exception e) {

flag=false;

}

return flag;

}public static boolean isSession(HttpSession newSession, String kskh) {

boolean flag = false;

HashMap maps = new HashMap();

try {

// 获得旧会话

maps = (HashMap) onlineSessionMap.get(kskh);

if(maps!=null){

if(maps.size()>1){

flag=true;

}

}

catch (Exception e) {

flag=false;

}

return flag;

}

/**

 * 

 */

public static void delSessionFromMap(String kskh){

if(onlineSessionMap.get(kskh)!=null){

onlineSessionMap.remove(kskh);

}

}

public static boolean containKey(String kskh){

return onlineSessionMap.containsKey(kskh);

}

}

 

过滤器

 

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

HttpServletRequest requestMy=(HttpServletRequest)request;

HttpServletResponse responseMy=(HttpServletResponse)response;

String requesetUrl=requestMy.getRequestURI();

System.out.println("================================");

if(requestMy.getSession()!=null&&requestMy.getSession().getAttribute("CH")!=null&&requesetUrl.indexOf(".jsp")>-1){

HttpSession session=requestMy.getSession();

//判断是否在登录状态

System.out.println("+++++++++++++++++++++++++++");

if(MySessionMapClass.isSession(session,requestMy.getSession().getAttribute("CH").toString())){

boolean flag=MySessionMapClass.isSameSession(session,requestMy.getSession().getAttribute("CH").toString());

//提示已在异地登陆

System.out.println("----------------------"+flag);

if(flag){

//获取不限制异地登陆的账号

//questMy.getSession().getAttribute("CH")

CommonService CommonService = (CommonService) this.getBean("commonService");

Map parameter=new HashMap();

parameter.put("CH", requestMy.getSession().getAttribute("CH").toString());

Map result = (Map) CommonService.queryForObject("get_code_fliter_login.select",parameter);

if(result!=null){

System.out.println("测试会员===========================");

if(result.get("CH")!=""&&result.get("CH").equals(requestMy.getSession().getAttribute("CH").toString())){

chain.doFilter(requestMy, responseMy);

}

}else{

System.out.println("---=======================-------"+flag);

response.setContentType("text/html;charset=UTF-8");

response.getWriter().write("<script type=\"text/javascript\">alert('您的账户已经在别处登录!');window.location.reload();</script>");

}

}else{

chain.doFilter(requestMy, responseMy);

}

}else{

chain.doFilter(requestMy, responseMy);

}

}else{

chain.doFilter(requestMy, responseMy);

}

}

 

 

<!--EndFragment-->
0
0
分享到:
评论
2 楼 HONGLINCHEN 2017-07-11  
楼主方便把源码 给我吗 我qq191623691
1 楼 duinibuhaome 2014-11-14  
各位高手们,有没有更好的方法呢 ,这样做起来有点麻烦呀,现在又需要将这个迁移到另外一个项目中,苦逼了。。。。

相关推荐

    一个账号同一时间只能登录一次

    "一个账号同一时间只能登录一次"的功能,通常被称为单点登录(Single Sign-On,简称SSO),它能够防止恶意用户同时在多个设备或浏览器会话中登录同一个账号,确保了用户的账户安全。下面将详细讲解如何实现这一功能...

    同一个账号,同一时间只能允许他登录一次

    在IT行业中,"同一个账号,同一时间只能允许他登录一次" 这个需求通常被称为单点登录(Single Sign-On, SSO)。这是一个重要的安全性措施,防止用户账户被多个设备或不同地点同时使用,以增加系统的安全性,防止未经...

    J2EE限制同一账号同一时刻只能一个用户登录使用,向QQ一样

    总之,实现“J2EE限制同一账号同一时刻只能一个用户登录使用”是一个涉及会话管理、安全性、用户体验等多个方面的综合任务。通过合理的架构设计和技术选型,我们可以构建出高效且安全的单点登录系统。

    在线聊天室。实现了同一个帐号同一时间在不同地点只能一个人登录,如果一个人使用则另一个人被迫下线

    本项目实现了一个特定的功能:确保同一账号在同一时间只能在一个地方登录,一旦有另一人在不同地点尝试登录,已登录的用户将被强制下线。这种设计模式被称为“会话独占”,它在许多在线服务中,特别是安全性要求较高...

    shiro实现单点登录(一个用户同一时刻只能在一个地方登录)

    通过这种方式,我们可以确保用户在同一时间只能在一个地方登录,增强了系统的安全性。在实际项目中,根据应用的具体需求,可能还需要处理跨域问题、令牌验证等复杂情况,但基础原理和上述步骤相似。

    利用spring security控制同一个用户只能一次登陆

    标题中的“利用Spring Security控制同一个用户只能一次登录”是指在基于Spring Security的Web应用程序中实现单点登录(Single Sign-On, SSO)的功能,确保同一时间只有一个设备或浏览器会话可以登录同一用户的账户。...

    Asp.net中实现同一用户名不能同时登陆

    因此,限制同一用户账户在同一时间只能在一个地方登录是非常必要的。 #### 二、实现原理及步骤 本文介绍的方法主要是通过ASP.NET中的全局状态存储机制来实现的,具体步骤如下: 1. **使用Application对象存储在线...

    JavaWeb实现同一帐号同一时间只能一个地点登陆(类似QQ登录的功能)

    - 防止多设备登录:限制用户在同一时间只能使用一个设备进行登录操作。 - 提升用户体验:避免用户因忘记退出而在其他地方造成的隐私泄露。 2. **实现过程**: a. **问题分析**: - 通常,登录信息会存储在...

    关于同一用户不能同时登录文件下载

    标题中的“关于同一用户不能同时登录文件下载”指的是在某些系统或应用中,设计者为了保护用户账号安全和维护系统稳定性,通常会限制同一用户在同一时间只能在一个设备或浏览器会话上登录。这一策略被称为“单点登录...

    PHP 实现一个账号仅允许一个用户登陆

    4. **会话唯一性**:为了确保一个账号只能在一个地方登录,我们可以创建一个额外的会话标志,例如`$_SESSION['single_login']`。在用户首次登录时,将其设置为真,并在数据库中记录该用户的会话ID。 5. **检测多处...

    防止同一用户同时登陆

    简单来说,就是确保系统中的每个用户在同一时间内只能在一个地方进行登录操作。这有助于避免因用户在不同设备或浏览器上同时保持登录状态而导致的安全问题或数据混淆情况发生。 #### 技术实现方法 实现这一功能的...

    防止同一账号多个用户同时登陆的解决方法.txt

    3. **处理登录冲突**:一旦检测到同一账号在不同位置尝试登录,系统会将之前的登录状态`Login_status`设置回0,强制下线之前的登录会话,从而确保同一账号在同一时间只能在一个地方登录。 #### 利用ASP.NET管理登录...

    ASP帐号只能同时登陆一个

    例如,如果一个用户在登录后没有注销,其他人就无法在同一时间用该账号登录,这样可以防止未授权的访问和潜在的恶意操作。 实现"ASP帐号只能同时登陆一个"的方法通常包括以下步骤: 1. **会话管理**:在用户成功...

    C#两个账号同时登录,后登录的账号将前一个账号挤掉

    当用户成功登录后,服务器会创建一个Session对象,并将用户的ID或其他唯一标识存储在其中,然后将Session ID通过Cookie返回给客户端。每次客户端请求时,都会携带这个Session ID,服务器据此识别用户。 2. **全局...

    防止一个用户登录多次的方法

    为了达到“同一时间只能登录一次”的目的,我们需要维护一个全局的记录来跟踪用户的登录状态。通常来说,可以使用服务器端的存储机制(如ASP.NET中的`Application`对象)来保存当前所有在线用户的列表。每当有新的...

    完美解决ASP.NET网页在同一时刻仅被一个登录用户占用的方案例子代码

    在多用户环境中,确保一个ASP.NET网页在同一时刻仅被一个登录用户占用是非常重要的,这涉及到用户体验、数据一致性和安全性。这种需求通常被称为“独占访问”或“会话锁定”。 在ASP.NET中,实现独占访问的一种常见...

    asp.net 防止同一用户同时登陆

    在ASP.NET开发中,确保系统安全性的一个关键方面是防止同一用户在同一时间从多个设备或浏览器窗口登录。这种安全措施不仅可以防止潜在的安全威胁,如账户冒用,还可以避免因多处登录而造成的资源浪费和数据冲突。...

    ASP.NET 2.0实现防止同一用户同时登陆

    在实际的应用场景中,为了提高系统的安全性以及用户体验,很多系统都需要实现同一个用户在同一时间只能在一个地方登录的功能。这样的设计可以有效避免用户账号被恶意盗用的风险,并且能够确保数据的安全性。在 ASP...

    同一账号不能同时登陆

    当用户登录成功后,服务器会生成一个唯一的Session ID,并将其发送给客户端,通常保存在Cookie中。每当客户端发送请求时,都会带上这个Session ID,服务器通过识别Session ID来判断是否为同一账号。 要实现“同一...

Global site tag (gtag.js) - Google Analytics