關於單用戶登陸

閒的蛋疼,本身弄了個單用戶登陸,第二次登陸能夠把第一次登陸的用戶擠下去...java

先上login的代碼:ajax

//...登陸驗證成功後...
//這裏得到uuid
String uuid = super.getUUID();
//保存登陸用戶的數據
LoginUser login = new LoginUser();
login.setId(user.getId());
login.setAccount(user.getAccount());
login.setRealName(user.getRealName());
login.setUuid(uuid);
	
//設置cookie
CookieUtil.deleteCookie(response,request, configInfo.getAdminCookieName());
CookieUtil.addCookie(response, configInfo.getAdminCookieName(), uuid);

//取得redis key
String key = configInfo.getRedisSessionListKey() + login.getAccount();
			
//緩存中是否存在
if(redisClient.isExist(key)){
    //從緩存刪除
    redisClient.del(key);
}
redisClient.setObject(key, login, 0);

//登陸成功
request.getSession().setAttribute(configInfo.getAdminSessionName(), login);

這裏我用了redis來保存登陸用戶redis

首先,先生成uuid放到cookie,session和緩存裏面,方便在後面驗證,spring

而後須要判斷在redis中是否存在,由於作的是第二次登陸把第一次登陸擠下去,那就把保存的對象中uuid更新一下,更新到最新,若是不更新的話就變成:第一個用戶登錄在線後,同帳號沒法登陸了.. json

接下來是過濾:緩存

//得到cookie
String uuid = CookieUtil.getCookieValue(httpRequest, configInfo.getAdminCookieName());
LoginUser user = (LoginUser)httpRequest.getSession().getAttribute(configInfo.getAdminSessionName());
String uri = httpRequest.getRequestURI();

String redisSessionKey = configInfo.getRedisSessionListKey() + user.getAccount();
//單用戶登陸驗證
if(redisClient.isExist(redisSessionKey)){
	LoginUser login = (LoginUser) redisClient.getObject(redisSessionKey);
	//這裏判斷redis中的用戶的uuid是否和cookie裏的一致
	if(!login.getUuid().equals(uuid)){
		//後臺ajax請求
		if(uri.contains("/json/")){
			//直接中斷
		    return;
		}
    		//與當前id不一樣,說明再其餘地方登陸過,因此返回從新登陸
		httpResponse.sendRedirect("/" + configInfo.getProjectName() + "/main.jsp");
		    return;
	}
}else{
	//用戶不在緩存,返回從新登陸
	httpResponse.sendRedirect("/" + configInfo.getProjectName() + "/index.jsp");
	return;
}

首先判斷一下緩存中是否有當前用戶(通常狀況下有的,可是redis重啓啊宕機啊可能會形成這狀況吧,加個驗證).cookie

主要判斷一下uuid是否一致就能夠了,由於登陸時咱們把生成的最新的uuid放到緩存裏了,若是不一致說明這個帳號在別的地方登陸過了,而後就能夠作其餘的操做了.session

最後,銷燬session時:jsp

public class AppSessionListener implements HttpSessionListener {
	
	@Override
	public void sessionCreated(HttpSessionEvent event) {
		System.out.println("Session建立");
	}

	@Override
	public void sessionDestroyed(HttpSessionEvent event) {
		System.out.println("Session銷燬");
		//得到spring中的bean
		ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(event.getSession().getServletContext());
		RedisClient redis = ctx.getBean(RedisClient.class);
		ConfigInfo configInfo = ctx.getBean(ConfigInfo.class);
		
		HttpSession session = event.getSession();
		//得到要銷燬的用戶
		LoginUser user = (LoginUser)session.getAttribute(configInfo.getAdminSessionName());
		
		if(user != null ){
			String key = configInfo.getRedisSessionListKey() + user.getAccount();
			if(redis.isExist(key)){
				redis.del(key);
				System.out.println("刪除緩存...");
			}
		}
		
	}
}

在session銷燬時把緩存刪一下...貌似不刪也行,不過會一直留在緩存裏面...ide

相關文章
相關標籤/搜索