redis+session單一登入實現
阿新 • • 發佈:2019-02-06
1.redis快取的方法
package com.zywlw.platform.service.redis.impl; import com.zywlw.platform.service.redis.RedisService; import org.apache.log4j.Logger; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.io.Serializable; import java.util.Set; import java.util.concurrent.TimeUnit; /** * Created with IntelliJ IDEA. * Description: * User: lyf * Date: 2018/2/26 */ @Service(value = "redisService") public class RedisServiceImpl implements RedisService { private RedisTemplate redisTemplate; private static final Logger LOGGER = Logger.getLogger(RedisService.class); @Resource(name = "redisTemplate") public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) { this.redisTemplate = redisTemplate; } /** * 批量刪除對應的value * * @param keys key陣列 */ public void removeBatchKey(final String... keys) { for (String key : keys) { removeByKey(key); } } /** * 批量刪除key * * @param pattern string */ public void removePattern(final String pattern) { Set<Serializable> keys = redisTemplate.keys(pattern); if (!CollectionUtils.isEmpty(keys)) { redisTemplate.delete(keys); } } /** * 刪除key * * @param key string */ public void removeByKey(final String key) { if (exists(key)) { redisTemplate.delete(key); } } /** * 判斷快取中是否有對應的value * * @param key key * @return boolean false or true */ public boolean exists(final String key) { return redisTemplate.hasKey(key); } /** * 讀取快取 * * @param key string * @return object */ public Object get(final String key) { Object result; ValueOperations<Serializable, Object> operations = redisTemplate .opsForValue(); result = operations.get(key); return result == null ? "" : result; } /** * 寫入快取,長久有效 * * @param key string * @param value object * @return boolean false or true */ public boolean setNoExpire(final String key, Object value) { boolean result = false; try { ValueOperations<Serializable, Object> operations = redisTemplate .opsForValue(); operations.set(key, value); result = true; } catch (DataAccessException e) { LOGGER.error("Write RedisCache failure:" + e); return result; } return result; } /** * 寫入快取 * * @param key string * @param value object * @param expireTime 過期時間 * @return boolean false or true */ public boolean setTakeOverTime(final String key, Object value, Long expireTime) { boolean result = false; try { ValueOperations<Serializable, Object> operations = redisTemplate .opsForValue(); operations.set(key, value); redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); result = true; } catch (DataAccessException e) { LOGGER.error("Write RedisCache failure:" + e); return result; } return result; } /** * 查詢hash表名為key欄位名為field的值 * @param userType 使用者型別sysUser/user * @param account 賬號名 */ public void isLogin(String userType, String account) { if (StringUtils.isEmpty(userType) || StringUtils.isEmpty(account)) { LOGGER.warn("Read RedisCache failure: Parameter cannot Empty"); } try { //查詢redis中鍵名為spring:session:sessions:sessionId格式的集合 Set<String> set = redisTemplate.keys("spring:session:sessions:" + "????????????????????????????????????"); for (String sessionId : set) { HashOperations<String, String, Object> operations = redisTemplate.opsForHash(); //判斷hash中是否有相應欄位,若有則比較userType中儲存的賬號名是否與當前賬號名相同,相同則刪除 if (operations.hasKey(sessionId, userType)) { Object value = operations.get(sessionId, userType); if (account.equals(value)) { operations.delete(sessionId, userType); } else { continue; } } } } catch (DataAccessException e) { LOGGER.error("Read RedisCache failure:" + e); } } /** * 向hash表寫入資料 * @param key 鍵名,即hash表名 * @param field 欄位名 * @param value 值 */ public void setKeyValue(String key, String field, String value) { if (StringUtils.isEmpty(key) || StringUtils.isEmpty(field) || StringUtils.isEmpty(value)) { LOGGER.warn("Read RedisCache failure: Parameter cannot Empty"); } redisTemplate.opsForHash().put(key, field, value); } /** * 判斷hash中是否有相應欄位 * @param key 鍵名,即hash表名 * @param field 欄位名 * @return */ public boolean existKeyValue(String key, String field) { if (StringUtils.isEmpty(key) || StringUtils.isEmpty(field)) { return false; } else { HashOperations<String, String, Object> operations = redisTemplate.opsForHash(); //redis中儲存的sessionId字首spring:session:sessions: return operations.hasKey("spring:session:sessions:" + key, field); } } }
2. login控制層的邏輯判斷
3.攔截器interceptor
package com.zywlw.platform.interceptor; import com.zywlw.platform.bean.SysUser; import com.zywlw.platform.constant.CommonConstant; import com.zywlw.platform.service.redis.RedisService; import com.zywlw.platform.util.UserSessionUtil; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.springframework.http.HttpStatus; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * Created with IntelliJ IDEA. * Description:系統使用者操作攔截器 * User: lyf * Date: 2018/2/26 */ public class SysAuthorityInterceptor implements HandlerInterceptor { /** * Log4j日誌處理 */ private static final Logger LOGGER = Logger.getLogger(SysAuthorityInterceptor.class); @Resource(name = "redisService") private RedisService redisService; @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) { String token = httpServletRequest.getHeader("token"); if (StringUtils.isEmpty(token)) { LOGGER.warn("sorry, you don't have the right to do it"); //返回狀態碼401 httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value()); return false; } SysUser sysuser = UserSessionUtil.getCurrentSysUserInfo(); HttpSession session = UserSessionUtil.getSession(); if (sysuser == null) { LOGGER.warn("Sorry, your information has expired, please login again"); //返回狀態碼401 httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value()); return false; } else if (!redisService.existKeyValue(session.getId(), CommonConstant.SYS_USER)) { LOGGER.warn("Sorry, this sysUserAccount is login in other place, please login again"); redisService.removeByKey("spring:session:sessions:" + session.getId()); session.invalidate(); //返回狀態碼406,掉線提示 httpServletResponse.setStatus(HttpStatus.NOT_ACCEPTABLE.value()); return false; } else { LOGGER.debug("SysAuthorityInterceptor pass :" + httpServletRequest.getRequestURL()); return true; } } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) { } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { } }