SpringMVC学习笔记3_通过redis缓存和cookie实现Session共享

来源:互联网 发布:mapreduce编程语言 编辑:程序博客网 时间:2024/06/05 14:46
摘要:

通过redis缓存和cookie实现单点登录


整体实现思路如下图所示。

Session的缓存机制


1.业务系统发起登录请求,调用SSO用户登录接口;


2.SSO登录接口的处理逻辑:

2.1 根据用户名和密码去数据库验证用户是否合法。

2.2 用户验证通过之后,生成SessionID,并返回给业务系统。

   同时以SessionID为key,存储用户信息到redis缓存中


  SSO登录接口代码:
  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<Permission> 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;    }


 

3.业务系统将返回的sessionID,存放到cookie里


  业务系统controller的代码:
 @RequestMapping("/login.ajax")    public    @ResponseBody    Map<String, Object> 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);            // 其他业务逻辑省略}


4.业务系统取得Session信息,并检验用户信息

业务系统的页面发起web请求时,

在自定义拦截器(继承自HandlerInterceptor)的preHandle方法里取得session信息,
并检查用户是否登录。
Session信息取得时,首先从cookie中取得SessionId,然后根据SessionId从redis取得用户信息

自定义拦截器的代码此处省略,请参照【SpringMVC学习笔记2_拦截器实现登录验证】,以下是取得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;    }



0 0
原创粉丝点击