通过redis缓存和cookie实现单点登录
整体实现思路如下图所示。
同时以SessionID为key,存储用户信息到redis缓存中
public JSONObject userLogin(@RequestBody JSONObject jsonObject){
UserLoginResponse userLoginResponss = new UserLoginResponse();
try {
logger.info("处理用户登录业务逻辑,接收报文"+jsonObject);
String msgWithDigesta=SecurityUtil.scfMatch(jsonObject.toString(), newXService.getPrivateKey());
//生成实体
User user = JSONObject.parseObject(msgWithDigesta,User.class);
//是否验证用户的密码
boolean isChechPassword = true;
User userInfo = anaService.loginCheckUserInfo(user,isChechPassword);
// 存储用户信息到redis缓存中
String ticket = anaService.storeUserLoginSessionInRedis(userInfo,user.getModuleCode());
userLoginResponss.setRetCode(RetCode.LOGIN_SUCCESS.getCode());
userLoginResponss.setRetMessage("用户登录成功");
userLoginResponss.setTicket(ticket);
userLoginResponss.setStatus(userInfo.getStatus());
userLoginResponss.setIsModifyPassword(userInfo.getIsModifyPassword());
} catch (Exception e) {
userLoginResponss.setRetCode(RetCode.LOGIN_FAILED.getCode());
userLoginResponss.setRetMessage(e.getMessage());
logger.info("插入用户数据到表中失败,原因:"+e.getMessage());
}
logger.info("返回处理用户登录业务逻辑结果,Result{[]}"+JSONObject.toJSONString(userLoginResponss));
return JSON.parseObject(JSONObject.toJSONString(userLoginResponss));
}
存储用户信息到redis缓存的代码:
/**
* 存储用户登录session信息到redis中
* @param userInfo
* @return
*/
public String storeUserLoginSessionInRedis(User userInfo,String moduleCode) {
// 存储用户ticket信息
// 使用AES加密登录用户ID生成SessionID,加密密码是配置文件里定义的64位字符串
String sessionId = AesUtil.encrypt(String.valueOf(userInfo.getUserId()), newXService.getBizkey());
String unique_ticket = userInfo.getSystemId()+sessionId+"_USER_LOGIN";
//
String ticket = userInfo.getSystemId()+sessionId+System.currentTimeMillis()+"_USER_LOGIN";
UserLoginSession userLoginSession = new UserLoginSession();
userLoginSession.setUserId(String.valueOf(userInfo.getUserId()));
userLoginSession.setUserName(userInfo.getUserName());
userLoginSession.setUserLoginName(userInfo.getUserLoginName());
// 获取权限
List permissions = getUserPermissions(userInfo.getUserId());
userLoginSession.setPermissions(permissions);
userLoginSession.setModuleCode(StringUtils.killNull(userInfo.getModuleCode()));
userLoginSession.setLastLoginTime(userInfo.getLastLoginTime());
userLoginSession.seteId(StringUtils.killNull(userInfo.geteId()));
userLoginSession.setSessionId(ticket);
userLoginSession.setUserInfo(userInfo);
//限制唯一登录,删除上一个用户信息
if (redisService.exists(unique_ticket))
redisService.del(redisService.get(unique_ticket));
redisService.set(unique_ticket, ticket);
logger.info("访问AnaController的login方法:放进redis"+ticket);
redisService.setKeyExpire((ticket).getBytes(),1800);
logger.info("userloginsession result ="+JSONObject.toJSONString(userLoginSession));
return ticket;
}
@RequestMapping("/login.ajax")
public
@ResponseBody
Map login(@RequestParam("username2") String username2,
@RequestParam("moduleCode2") String moduleCode2,
@RequestParam("password2") String password2, String requestUrl, HttpServletResponse response) {
// 其他业务逻辑省略
String sessionId = userBySso.getTicket();
Cookie cookie = new Cookie("CORE_SESSION", sessionId);
cookie.setPath("/");
response.addCookie(cookie);
// 其他业务逻辑省略
}
业务系统的页面发起web请求时,
在自定义拦截器(继承自HandlerInterceptor)的preHandle方法里取得session信息, public UserLoginSession getUserLoginSession(HttpServletRequest req) {
logger.info("访问getUserLoginSession");
String sessionId = "";
Cookie[] cookie = req.getCookies();
if (cookie == null) {
return null;
}
for (int i = 0; i < cookie.length; i++) {
Cookie cook = cookie[i];
if (cook.getName().equals("CORE_SESSION")) {
sessionId = cook.getValue().toString();
}
}
logger.info("访问getUserLoginSession获取sessionId: " + sessionId);
if ("".equals(sessionId)) {
return null;
}
String UserLoginSessionStr = redisService.get(sessionId);
logger.info("访问getUserLoginSession获取USERLOGINSESSION: " + UserLoginSessionStr);
if (null == UserLoginSessionStr || "".equals(UserLoginSessionStr)) {
return null;
}
UserLoginSession userLoginSession = (UserLoginSession) JSONObject.toJavaObject(JSONObject.parseObject(UserLoginSessionStr), UserLoginSession.class);
logger.info("访问getUserLoginSession获取USER_ID成功: " + userLoginSession.getUserId());
redisService.setKeyExpire((sessionId).getBytes(), 1800);
redisService.setKeyExpire((userLoginSession.getTicketRole()).getBytes(),1800);
return userLoginSession;
}