JEE保证登陆唯一

2024-05-26 01:48
文章标签 登陆 唯一 保证 jee

本文主要是介绍JEE保证登陆唯一,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在做上个课程项目的时候就遇到过这个问题,当时的实现方式 是通过全局的监听来实现的,通过session 来标记一个用户的登陆状态,只有当当前用户注销时 用户用同样的账号登陆才会成功,这个做法存在多个问题,其中主要问题是判断用户登出,如果用户点击注销键,这个没问题,但是如果用户异常登出呢?   当然也不是没有办法,首先 我们可以设立监听事件  unload   这样在网页关闭的时候会触发这个时间,  但是这个事件会被多个动作触发,部分动作并不表示退出,比如说网页刷新等,另外直接关闭浏览器主窗体也不会触发标签页的unload事件,     当然还有方法补救,  我们通过session的 生命周期来,  如果用户在session 生命周期内没有与服务器发生交互 我们就认为用户已经离开,这个也是一个较为稳妥的方法,这个方法存在一个问题  如果用户异常登出,  那么用户需要等待当前session 会话结束才能再次登陆,  这个也是我上个项目没有实现这个功能的主要理由


现在换了一种决策,我认为登陆是可以互顶的,后登陆的会顶掉先登录的人,这样的逻辑思维也比较正常,如果一个人多处登陆,那么他使用最后登陆的设备与服务器交互的可能性也最大,如果存在异常一个人账号被多个人知晓,他也能通过互顶账号来实现保护自己的账号安全,检查互顶频率 也可以实现账号冻结等功能,


扯完背景了 扯点实在的

这里采用的方式是struts 的拦截器   我通过静态的map 存储userid 到 sessionid 的映射    然后通过检查映射来完成引导


这里复用了我一个测试的项目 代码逻辑就不用管了  只看实现就成


首先定义通用方法   使用单例 管理map 对象 同时 考虑多线程访问

package com.yueguang.util;import java.util.HashMap;
import java.util.concurrent.Semaphore;public class AccountUtil {private static AccountUtil accountUtil= new AccountUtil();private HashMap<String, String> accountToSession;Semaphore semaphore;private AccountUtil() {accountToSession = new HashMap<String, String>();semaphore = new Semaphore(1);}public static AccountUtil getAccountUtil() {return accountUtil;}public synchronized void registerSessionid(String account, String sessionid) {try {semaphore.acquire();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}accountToSession.put(account, sessionid);System.out.println(account+" " + sessionid);semaphore.release();}public synchronized boolean checkSessionid(String account, String sessionid) {try {semaphore.acquire();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}String old_sessionid = accountToSession.get(account);semaphore.release();System.out.println("1111   "   + old_sessionid);System.out.println(account + " "+ sessionid);if (old_sessionid != null && old_sessionid.equals(sessionid)) {return true;} else {return false;}}}

其次定义拦截器   拦截请求 交给验证  如果验证失败 引导到重新登录的页面

package com.yueguang.Interceptor;import java.util.Map;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.SessionAware;import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.yueguang.util.AccountUtil;public class LoginInterceptor extends AbstractInterceptor {Map<String, Object> session;HttpServletRequest request;@Overridepublic String intercept(ActionInvocation actionInvocation) throws Exception {// TODO Auto-generated method stubAccountUtil accountUtil = AccountUtil.getAccountUtil();session = actionInvocation.getInvocationContext().getSession();if (session == null) {return "reLogin";}String userid = (String) session.get("userid");if (userid == null) {return "reLogin";}request = ServletActionContext.getRequest();String sessionid = (String) request.getSession().getId();if (accountUtil.checkSessionid(userid, sessionid)) {return actionInvocation.invoke();} else {return "reLogin";}}
}

然后在登陆成功的时候  想session 中注入用户名    并且向map中 注入键值对


// 实现登陆功能的通用模块private String loginUtil(Class c) {Object someone = baseDao.load(c, username);Method m;try {m = c.getMethod("getPassword", null);if (someone != null&& ((String) m.invoke(someone)).equals(password)) {request.setAttribute(c.getName().substring(c.getName().lastIndexOf(".") + 1),someone);<span style="color:#ff0000;">AccountUtil accountUtil = AccountUtil.getAccountUtil();accountUtil.registerSessionid(username, request.getSession().getId());session.put("userid", username);</span>return SUCCESS;}} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}this.addActionError("用户  " + username + "用户类型 "+ c.getName().substring(c.getName().lastIndexOf(".") + 1)+ " 登陆失败     ");return "fail";}

配置struts 拦截器

<package name="checkLogin" extends="struts-default"><interceptors><interceptor name="login" class="com.yueguang.Interceptor.LoginInterceptor"/><interceptor-stack name="login_default"><interceptor-ref name="login"/><interceptor-ref name="defaultStack"/></interceptor-stack></interceptors><default-interceptor-ref name="login_default"/></package>

让需要改拦截器的模块扩展 这个包

<package name="test" namespace="/test" extends="<span style="color:#ff0000;">checkLogin</span>"> <global-results><result name="reLogin">/Login.jsp</result></global-results><action name="haha" class="testAction"  method="test"><result name="success">/Error.jsp</result>  <result name="fail" type="chain"><param name="actionName">kaka</param><param name="namespace">/test</param></result></action><action name="kaka" class="testAction"  method="testkaka"><result name="success">/Error.jsp</result>  <result name="fail">/Login.jsp</result></action></package> 


这个方法能实现单人登陆的效果,但是存在个问题是  转发的请求 也会被拦截器 检测  这个会导致效率低下  我正在查不拦截 dispatcher 的方法


这篇关于JEE保证登陆唯一的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1003219

相关文章

如何保证android程序进程不到万不得已的情况下,不会被结束

最近,做一个调用系统自带相机的那么一个功能,遇到的坑,在此记录一下。 设备:红米note4 问题起因 因为自定义的相机,很难满足客户的所有需要,比如:自拍杆的支持,优化方面等等。这些方面自定义的相机都不比系统自带的好,因为有些系统都是商家定制的,难免会出现一个奇葩的问题。比如:你在这款手机上运行,无任何问题,然而你换一款手机后,问题就出现了。 比如:小米的红米系列,你启用系统自带拍照功能后

Android的登陆MD5加密

1:导入代码 public class MD5Util {private static final String TAG = "MD5Util";/**** MD5加码 生成32位md5码*/public static String string2MD5(String inStr) {Log.e(TAG, "string2MD5: -------------------------");Mess

集群环境下为雪花算法生成全局唯一机器ID策略

雪花算法是生成数据id非常好的一种方式,机器id是雪花算法不可分割的一部分。但是对于集群应用,让不同的机器自动产生不同的机器id传统做法就是针对每一个机器进行单独配置,但这样做不利于集群水平扩展,且操作过程非常复杂,所以每一个机器在集群环境下是一个头疼的问题。现在借助spring+redis,给出一种策略,支持随意水平扩展,肥肠好用。 大致策略分为4步: 1.对机器ip进行hash,对某一个(大于

超强台风摩羯逼近!或成大陆史上最强登陆台风,防御措施需到位

超强台风摩羯逼近!或成大陆史上最强登陆台风,防御措施需到位 摩羯即将登录,各位兄弟姐妹注意安全!#大型纪录片#摩羯#台风 推荐阅读: 一夜蒸发2万亿!英伟达市值遭遇滑铁卢 《火速围观!黑神话悟空IP山西空心月饼,又一波抢购热潮即将来袭》 直击心灵!佤写不来情歌,却意外火爆全网,你听了没? 警告!明年6至9月假期空窗期,你的旅行计划何去何从? 独家揭秘!雷军豪赠《黑神话:悟空》给王腾,

前端vue项目生成唯一的uuid

一、使用步骤 1.安装uuid 代码如下(示例): npm install -S uuid 2.在需要使用uuid的.vue文件中生成并存储uuid 代码如下(示例): import { v4 as uuidv4 } from 'uuid';mounted () {let sid=''if(localStorage.getItem('sid')){sid=localStorage.g

window7 登陆机制 CredentialProvider

下面是我自己弄的一个例子,就是自定义window7登陆, 1.1 首先拦截了其余的登陆方式 1.2 简单的模拟智能卡登陆模式 1.3 模拟智能卡登陆失败,需要输入window登陆密码 才能进入 1.4 里面有俩个项目,看清楚了,下面是项目结构 1.5 关于自定义登陆的一些文章,有详细的介绍 http://baike.baidu.com/link?url=AIJWwcDTVUxlx0CTO

【python 百度指数抓取】python 模拟登陆百度指数,图像识别百度指数

一、算法思想 目的奔着去抓取百度指数的搜索指数,搜索指数的爬虫不像是其他爬虫,难度系数很高,分析之后发现是图片,坑爹的狠,想了下,由于之前做过身份证号码识别,验证码识别之类,豁然开朗,不就是图像识别麽,图像识别我不怕你,于是就有了思路,果然有异曲同工之妙,最后成功被我攻破了,大致思路如下: 1、首先得模拟登陆百度账号(用selenium+PhantomJS模拟登陆百度,获取cookie) 2

Java 面试题:从源码理解 ThreadLocal 如何解决内存泄漏 ConcurrentHashMap 如何保证并发安全 --xunznux

文章目录 ThreadLocalThreadLocal 的基本原理ThreadLocal 的实现细节内存泄漏源码使用场景 ConcurrentHashMap 怎么实现线程安全的CAS初始化源码添加元素putVal方法 ThreadLocal ThreadLocal 是 Java 中的一种用于在多线程环境下存储线程局部变量的机制,它可以为每个线程提供独立的变量副本,从而避免多个线

等式(数论/唯一分解定理)

链接: https://www.nowcoder.com/acm/contest/90/F 来源:牛客网 题目描述 给定n,求1/x + 1/y = 1/n (x<=y)的解数。(x、y、n均为正整数) 输入描述: 在第一行输入一个正整数T。接下来有T行,每行输入一个正整数n,请求出符合该方程要求的解数。(1<=n<=1e9) 输出描述: 输出符合该方程要求的解数。

php 登陆后台验证代码

前台表单: <span style="font-size:18px;"><span style="font-size:18px;"><form action="check_login.php" name="loginform" method="post">帐号: <input type="text" name="name" />密码:<input