简单的防止重复登录实现

这个实现利用的是struts2的拦截器,大家也可以试着用filter+servlet来实现,原理都是一样的。

memcache的安装与拦截器的配置可以在我的文章里找到,我就不赘述了。

首先我们看下思路:



 我们看到多台web服务器共享一台memcache服务器,这个memcache就是存储用户登录信息的作用。

在memcached中以map(key,value)形式存储数据,我们就可以用登录名作key,每一个浏览器访问节点的sessionId作value,用户登录更新对应登录名的sessionId,这样用户在做与服务器通信的操作时查询一次memcache看其中存储的sessionId是不是与自己的对应,不对应就说明已经有人再另一个地方登陆了,这时就可以把此用户踢掉了。这个原理比较简单,仔细想想就明白了。

下面是一段登录的代码

// 用户名
String usrName = request.getParameter(Constants.USER_NAME);
// 密码
String passwd = request.getParameter(Constants.USER_PASSWD);
// 请求的类型
String method = ServletActionContext.getRequest().getMethod();
boolean isGet = "GET".equalsIgnoreCase(method);// 如果为GET
// 如果是地址栏输入网址提交
if (isGet)
	throw new LoginException("-1053");// 禁止get方式登录
// 判断是否输入了用户名,密码
if (StringUtils.hasText(usrName) && StringUtils.hasText(passwd)) {
	// 验证登陆
	boolean loginSuccess = loginService.login(usrName, passwd);
	// 登录成功
	if (loginSuccess) {
// 存储登录信息至memcache
boolean putSuccess = MemcacheHelper.setMap(usrName, request.getSession().getId());
if (putSuccess) {
	request.setAttribute(Constants.SUCCESS, "SUCCESS");
	request.setAttribute(Constants.PATH, path);
	return SUCCESS;
} else {
	throw new LoginException("-1011");// 登录失败,请重试
}
	}
}
throw new LoginException("-1001");// 用户名,密码必须输入!

 这段代码比较简单,就是把新登录的sessionId放到memcache里替换前面的。

关键在于连接器中对于sessionId的比对,拦截器代码:

// 此处去memcache查是否是正在使用用户
String sessionId = (String) MemcacheHelper.getValue(user.getLoginName());
String thisSessionId = request.getSession().getId();
logger.debug("从memcache取值,session值:" + sessionId);
/** 判断memcache是否有值 */
if (!StringUtils.hasText(sessionId)) {
	logger.error("查询memcache失败");
	request.getSession().invalidate();
	// 返回登录页面
	if (isAjax) {
		response.sendError(1011, "登录信息获取失败,请重新登录");
		response.flushBuffer();
	} else
		throw new LoginException("-1011");
}

/** 判断服务器session是否有值 */
if (!StringUtils.hasText(thisSessionId)) {
	logger.error("服务器登录信息获取失败");
	request.getSession().invalidate();
	if (isAjax) {
		response.sendError(1011, "登录信息获取失败,请重新登录");
		response.flushBuffer();
	} else
		throw new LoginException("-1011");
}

/** 当memcache中存储登录用户与此用户对应正确时 */
if (!sessionId.equals(thisSessionId)) {
	logger.error("该用户已在其他地点登录");
	request.getSession().invalidate();
	if (isAjax) {
		response.sendError(1010, "该用户已在其他地点登录");
		response.flushBuffer();
	} else
		throw new LoginException("-1010");
}

 判断memcache里存的值是不是该用户的,不是就踢了@_@

猜你喜欢

转载自286.iteye.com/blog/1405734
今日推荐