diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/LoginController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/LoginController.java index 8d47b01..27fcbc0 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/LoginController.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/LoginController.java @@ -4,10 +4,12 @@ import cn.hutool.core.util.RandomUtil; import com.alibaba.fastjson.JSONObject; import com.aliyuncs.exceptions.ClientException; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.annotation.RequiresRoles; import org.jeecg.common.api.vo.Result; @@ -21,10 +23,7 @@ import org.jeecg.common.util.*; import org.jeecg.common.util.encryption.EncryptedString; import org.jeecg.config.JeecgBaseConfig; import org.jeecg.modules.base.service.BaseCommonService; -import org.jeecg.modules.system.entity.SysDepart; -import org.jeecg.modules.system.entity.SysRoleIndex; -import org.jeecg.modules.system.entity.SysTenant; -import org.jeecg.modules.system.entity.SysUser; +import org.jeecg.modules.system.entity.*; import org.jeecg.modules.system.model.SysLoginModel; import org.jeecg.modules.system.service.*; import org.jeecg.modules.system.service.impl.SysBaseApiImpl; @@ -38,7 +37,6 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.*; -import java.util.stream.Collectors; /** * @Author scott @@ -58,16 +56,22 @@ public class LoginController { @Autowired private ISysLogService logService; @Autowired - private RedisUtil redisUtil; + private RedisUtil redisUtil; @Autowired - private ISysDepartService sysDepartService; + private ISysDepartService sysDepartService; @Autowired - private ISysDictService sysDictService; + private ISysDictService sysDictService; @Resource private BaseCommonService baseCommonService; @Autowired private JeecgBaseConfig jeecgBaseConfig; + @Autowired + private ISysUserRoleService sysUserRoleService; + + @Autowired + private ISysRoleService sysRoleService; + private final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890"; @ApiOperation("登录接口") @@ -81,25 +85,25 @@ public class LoginController { } // step.1 验证码check - String captcha = sysLoginModel.getCaptcha(); - if(captcha==null){ - result.error500("验证码无效"); - return result; - } - String lowerCaseCaptcha = captcha.toLowerCase(); + String captcha = sysLoginModel.getCaptcha(); + if(captcha==null){ + result.error500("验证码无效"); + return result; + } + String lowerCaseCaptcha = captcha.toLowerCase(); // 加入密钥作为混淆,避免简单的拼接,被外部利用,用户自定义该密钥即可 - String origin = lowerCaseCaptcha+sysLoginModel.getCheckKey()+jeecgBaseConfig.getSignatureSecret(); + String origin = lowerCaseCaptcha+sysLoginModel.getCheckKey()+jeecgBaseConfig.getSignatureSecret(); String realKey = Md5Util.md5Encode(origin, "utf-8"); Object checkCode = redisUtil.get(realKey); //当进入登录页时,有一定几率出现验证码错误 #1714 if(checkCode==null || !checkCode.toString().equals(lowerCaseCaptcha)) { - log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", sysLoginModel.getCheckKey(), lowerCaseCaptcha, checkCode); + log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", sysLoginModel.getCheckKey(), lowerCaseCaptcha, checkCode); result.error500("验证码错误"); // 改成特殊的code 便于前端判断 result.setCode(HttpStatus.PRECONDITION_FAILED.value()); return result; } - + // step.2 校验用户是否存在且有效 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SysUser::getUsername,username); @@ -161,11 +165,19 @@ public class LoginController { //update-begin---author:liusq ---date:2022-06-29 for:接口返回值修改,同步修改这里的判断逻辑----------- //update-end---author:scott ---date::2022-06-20 for:vue3前端,支持自定义首页-------------- log.info("2 获取用户信息耗时 (首页面配置)" + (System.currentTimeMillis() - start) + "毫秒"); - + + List userRole = sysUserRoleService.list(new QueryWrapper().lambda().eq(SysUserRole::getUserId, sysUser.getId())); + if(ObjectUtils.isNotEmpty(userRole)){ + String rollId = userRole.get(0).getRoleId(); + SysRole sysRole = sysRoleService.getById(rollId); + if(ObjectUtils.isNotEmpty(sysRole)){ + sysUser.setRoleCode(sysRole.getRoleCode()); + } + } obj.put("userInfo",sysUser); obj.put("sysAllDictItems", sysDictService.queryAllDictItems()); log.info("3 获取用户信息耗时 (字典数据)" + (System.currentTimeMillis() - start) + "毫秒"); - + result.setResult(obj); result.success(""); } @@ -173,7 +185,7 @@ public class LoginController { return result; } - + /** * 退出登录 * @param request @@ -183,31 +195,31 @@ public class LoginController { @RequestMapping(value = "/logout") public Result logout(HttpServletRequest request,HttpServletResponse response) { //用户退出逻辑 - String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN); - if(oConvertUtils.isEmpty(token)) { - return Result.error("退出登录失败!"); - } - String username = JwtUtil.getUsername(token); + String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN); + if(oConvertUtils.isEmpty(token)) { + return Result.error("退出登录失败!"); + } + String username = JwtUtil.getUsername(token); LoginUser sysUser = sysBaseApi.getUserByName(username); - if(sysUser!=null) { + if(sysUser!=null) { //update-begin--Author:wangshuai Date:20200714 for:登出日志没有记录人员 baseCommonService.addLog("用户名: "+sysUser.getRealname()+",退出成功!", CommonConstant.LOG_TYPE_1, null,sysUser); //update-end--Author:wangshuai Date:20200714 for:登出日志没有记录人员 - log.info(" 用户名: "+sysUser.getRealname()+",退出成功! "); - //清空用户登录Token缓存 - redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token); - //清空用户登录Shiro权限缓存 + log.info(" 用户名: "+sysUser.getRealname()+",退出成功! "); + //清空用户登录Token缓存 + redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token); + //清空用户登录Shiro权限缓存 redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId()); //清空用户的缓存信息(包括部门信息),例如sys:cache:user:: redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername())); //调用shiro的logout SecurityUtils.getSubject().logout(); - return Result.ok("退出登录成功!"); - }else { - return Result.error("Token无效!"); - } + return Result.ok("退出登录成功!"); + }else { + return Result.error("Token无效!"); + } } - + /** * 获取访问量 * @return @@ -238,7 +250,7 @@ public class LoginController { result.success("登录成功"); return result; } - + /** * 获取访问量 * @return @@ -248,19 +260,19 @@ public class LoginController { Result>> result = new Result>>(); Calendar calendar = new GregorianCalendar(); calendar.set(Calendar.HOUR_OF_DAY,0); - calendar.set(Calendar.MINUTE,0); - calendar.set(Calendar.SECOND,0); - calendar.set(Calendar.MILLISECOND,0); - calendar.add(Calendar.DAY_OF_MONTH, 1); - Date dayEnd = calendar.getTime(); - calendar.add(Calendar.DAY_OF_MONTH, -7); - Date dayStart = calendar.getTime(); - List> list = logService.findVisitCount(dayStart, dayEnd); + calendar.set(Calendar.MINUTE,0); + calendar.set(Calendar.SECOND,0); + calendar.set(Calendar.MILLISECOND,0); + calendar.add(Calendar.DAY_OF_MONTH, 1); + Date dayEnd = calendar.getTime(); + calendar.add(Calendar.DAY_OF_MONTH, -7); + Date dayStart = calendar.getTime(); + List> list = logService.findVisitCount(dayStart, dayEnd); result.setResult(oConvertUtils.toLowerCasePageList(list)); return result; } - - + + /** * 登陆成功选择用户当前部门 * @param user @@ -274,7 +286,7 @@ public class LoginController { LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal(); username = sysUser.getUsername(); } - + //获取登录部门 String orgCode= user.getOrgCode(); //获取登录租户 @@ -290,7 +302,7 @@ public class LoginController { /** * 短信登录接口 - * + * * @param jsonObject * @return */ @@ -302,18 +314,18 @@ public class LoginController { //手机号模式 登录模式: "2" 注册模式: "1" String smsmode=jsonObject.get("smsmode").toString(); log.info("-------- IP:{}, 手机号:{},获取绑定验证码", clientIp, mobile); - + if(oConvertUtils.isEmpty(mobile)){ result.setMessage("手机号不允许为空!"); result.setSuccess(false); return result; } - + //update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906 String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+mobile; Object object = redisUtil.get(redisKey); //update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906 - + if (object != null) { result.setMessage("验证码10分钟内,仍然有效!"); result.setSuccess(false); @@ -334,7 +346,7 @@ public class LoginController { //随机数 String captcha = RandomUtil.randomNumbers(6); JSONObject obj = new JSONObject(); - obj.put("code", captcha); + obj.put("code", captcha); try { boolean b = false; //注册模板 @@ -358,7 +370,7 @@ public class LoginController { } return result; } - + /** * smsmode 短信模板方式 0 .登录模板、1.注册模板、2.忘记密码模板 */ @@ -376,12 +388,12 @@ public class LoginController { result.setSuccess(false); return result; } - + //update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906 //验证码10分钟内有效 redisUtil.set(redisKey, captcha, 600); //update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906 - + //update-begin--Author:scott Date:20190812 for:issues#391 //result.setResult(captcha); //update-end--Author:scott Date:20190812 for:issues#391 @@ -394,11 +406,11 @@ public class LoginController { } return result; } - + /** * 手机号登录接口 - * + * * @param jsonObject * @return */ @@ -418,7 +430,7 @@ public class LoginController { if(!result.isSuccess()) { return result; } - + String smscode = jsonObject.getString("captcha"); //update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906 @@ -469,7 +481,7 @@ public class LoginController { //3.设置登录用户信息 obj.put("userInfo", sysUser); - + //4.设置登录部门 List departs = sysDepartService.queryUserDeparts(sysUser.getId()); obj.put("departs", departs); @@ -496,7 +508,7 @@ public class LoginController { obj.put("sysAllDictItems", sysDictService.queryAllDictItems()); } //end-begin---author:scott ---date:2024-01-05 for:【QQYUN-7802】前端在登录时加载了两次数据字典,建议优化下,避免数据字典太多时可能产生的性能问题 #956--- - + result.setResult(obj); result.success("登录成功"); return result; @@ -530,13 +542,13 @@ public class LoginController { String code = RandomUtil.randomString(BASE_CHECK_CODES,4); //存到redis中 String lowerCaseCode = code.toLowerCase(); - + //update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906 // 加入密钥作为混淆,避免简单的拼接,被外部利用,用户自定义该密钥即可 String origin = lowerCaseCode+key+jeecgBaseConfig.getSignatureSecret(); String realKey = Md5Util.md5Encode(origin, "utf-8"); //update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906 - + redisUtil.set(realKey, lowerCaseCode, 60); log.info("获取验证码,Redis key = {},checkCode = {}", realKey, code); //返回前端 @@ -557,11 +569,11 @@ public class LoginController { @RequiresRoles({"admin"}) @GetMapping(value = "/switchVue3Menu") public Result switchVue3Menu(HttpServletResponse response) { - Result res = new Result(); + Result res = new Result(); sysPermissionService.switchVue3Menu(); return res; } - + /** * app登录 * @param sysLoginModel @@ -574,7 +586,7 @@ public class LoginController { String username = sysLoginModel.getUsername(); String password = sysLoginModel.getPassword(); JSONObject obj = new JSONObject(); - + //update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户 if(isLoginFailOvertimes(username)){ return result.error500("该用户登录失败次数过多,请于10分钟后再次登录!"); @@ -586,7 +598,7 @@ public class LoginController { if(!result.isSuccess()) { return result; } - + //2. 校验用户名或密码是否正确 String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt()); String syspassword = sysUser.getPassword(); @@ -597,17 +609,17 @@ public class LoginController { result.error500("用户名或密码错误"); return result; } - + //3.设置登录部门 String orgCode = sysUser.getOrgCode(); if(oConvertUtils.isEmpty(orgCode)) { //如果当前用户无选择部门 查看部门关联信息 - + List departs = sysDepartService.queryUserDeparts(sysUser.getId()); //update-begin-author:taoyan date:20220117 for: JTC-1068【app】新建用户,没有设置部门及角色,点击登录提示暂未归属部,一直在登录页面 使用手机号登录 可正常 if (departs == null || departs.size() == 0) { /*result.error500("用户暂未归属部门,不可登录!"); - + return result;*/ }else{ orgCode = departs.get(0).getOrgCode(); @@ -625,7 +637,7 @@ public class LoginController { //5. 设置登录用户信息 obj.put("userInfo", sysUser); - + //6. 生成token String token = JwtUtil.sign(username, syspassword); // 设置超时时间 @@ -799,7 +811,7 @@ public class LoginController { return result; } - + /** * 图形验证码 * @param sysLoginModel @@ -824,5 +836,5 @@ public class LoginController { redisUtil.removeAll(realKey); return Result.ok(); } - -} \ No newline at end of file + +}