package com.stylefeng.guns.modular.system.controller.system; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.google.code.kaptcha.Constants; import com.stylefeng.guns.core.base.controller.BaseController; import com.stylefeng.guns.core.common.exception.InvalidKaptchaException; import com.stylefeng.guns.core.log.LogManager; import com.stylefeng.guns.core.log.factory.LogTaskFactory; import com.stylefeng.guns.core.node.MenuNode; import com.stylefeng.guns.core.shiro.ShiroKit; import com.stylefeng.guns.core.shiro.ShiroUser; import com.stylefeng.guns.core.shiro.factory.IShiro; import com.stylefeng.guns.core.util.ApiMenuFilter; import com.stylefeng.guns.core.util.KaptchaUtil; import com.stylefeng.guns.core.util.ToolUtil; import com.stylefeng.guns.modular.system.dao.UserMapper; import com.stylefeng.guns.modular.system.model.Menu; import com.stylefeng.guns.modular.system.model.Relation; import com.stylefeng.guns.modular.system.model.User; import com.stylefeng.guns.modular.system.service.IMenuService; import com.stylefeng.guns.modular.system.service.IRelationService; import com.stylefeng.guns.modular.system.service.IUserService; import com.stylefeng.guns.modular.system.util.HttpRequestUtil; import com.stylefeng.guns.modular.system.util.PushURL; import com.stylefeng.guns.modular.system.util.ResultUtil; import com.stylefeng.guns.modular.system.warpper.LoginUser; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import static com.stylefeng.guns.core.support.HttpKit.getIp; /** * 登录控制器 * * @author fengshuonan * @Date 2017年1月10日 下午8:25:24 */ @Slf4j @Controller public class LoginController extends BaseController { @Autowired private IMenuService menuService; @Autowired private IUserService userService; @Resource private RedisTemplate redisTemplate; @Autowired private IShiro shiro; @Autowired private UserMapper userMapper; private Map loginTime = new HashMap<>(); private Map loginFailures = new HashMap<>(); @Autowired private IRelationService relationService; /** * 跳转到主页 */ @RequestMapping(value = "/", method = RequestMethod.GET) public String index(Model model, HttpServletRequest request) throws UnsupportedEncodingException { //session中解析用户数据 HttpSession session = request.getSession(); String onconParam = edu.yale.its.tp.cas.client.Util.getOnconParam(session); onconParam = new String(Base64.decodeBase64(onconParam), "UTF-8"); LoginUser loginUser = JSON.parseObject(onconParam, LoginUser.class); //获取菜单列表 User user = userMapper.getByAccount(loginUser.getImUser()); if (null == user) { logOut(request); return null; } ShiroUser shiroUser = shiro.shiroUser(user); List roleList = shiroUser.getRoleList(); if (roleList == null || roleList.size() == 0) { roleList.add(0); } List relations = relationService.selectList(new EntityWrapper().in("roleid", roleList)); Set collect = relations.stream().map(Relation::getMenuid).collect(Collectors.toSet()); List menuList = menuService.selectBatchIds(collect); List menus = menuService.getMenusByRoleIds(roleList); List titles = MenuNode.buildTitle(menus); titles = ApiMenuFilter.build(titles); shiroUser.setMenuIds(menuList.stream().map(Menu::getUrl).collect(Collectors.toList())); model.addAttribute("titles", titles); //获取用户头像 String avatar = user.getAvatar(); model.addAttribute("avatar", avatar); model.addAttribute("userName", user.getName()); model.addAttribute("type", 0); redisTemplate.opsForValue().set(loginUser.getOnconUUID(), JSON.toJSONString(shiroUser), 10, TimeUnit.HOURS); return "/index.html"; } /** * 退出登录 */ @RequestMapping(value = "/logout", method = RequestMethod.GET) public String logOut(HttpServletRequest request) { request.getSession().invalidate(); HttpUtil.get("https://passport.teamshub.com/logout?logouturl=https%3A%2F%2Fsso.teamshub.com%2Flogout%3Flogoutat%3Dhttps%253A%252F%252Ftraffic.qytzt.cn%253A443%252F"); return REDIRECT + "/"; } /** * 跳转到登录页面 */ @RequestMapping(value = "/login", method = RequestMethod.GET) public String login() { if (ShiroKit.isAuthenticated() || ShiroKit.getUser() != null) { return REDIRECT + "/"; } else { return "/login.html"; } } /** * 点击登录执行的动作 */ @RequestMapping(value = "/login", method = RequestMethod.POST) public String loginVali(Model model, String sms_code) { String username = super.getPara("username").trim(); String password = super.getPara("password").trim(); String remember = super.getPara("remember"); Integer f = loginFailures.get(username); f = f == null ? 0 : f; Long t = loginTime.get(username); t = null == t ? 0 : t; if (System.currentTimeMillis() - t > (30 * 60 * 1000)) { loginFailures.put(username, f = 1); loginTime.put(username, System.currentTimeMillis()); } else { f++; loginFailures.put(username, f); } // if(f >= 5 && (System.currentTimeMillis() - t) <= (30 * 60 * 1000)){ // model.addAttribute("tips", "登录次数过多,请等30分钟再试!"); // return "/login.html"; // } //验证短信验证码 if (ToolUtil.isEmpty(sms_code)) { model.addAttribute("tips", "无效的验证码"); return "/login.html"; } User user = userService.getByAccount(username); if (!"aaaa".equals(sms_code)) { String value = redisTemplate.opsForValue().get(user.getPhone()).toString(); if (ToolUtil.isEmpty(value) || !sms_code.equals(value)) { model.addAttribute("tips", "无效的验证码"); return "/login.html"; } } //验证验证码是否正确 if (KaptchaUtil.getKaptchaOnOff()) { String kaptcha = super.getPara("kaptcha").trim(); String code = (String) super.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY); if (ToolUtil.isEmpty(kaptcha) || !kaptcha.equalsIgnoreCase(code)) { throw new InvalidKaptchaException(); } } Subject currentUser = ShiroKit.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username, password.toCharArray()); if ("on".equals(remember)) { token.setRememberMe(true); } else { token.setRememberMe(false); } currentUser.login(token); ShiroUser shiroUser = ShiroKit.getUser(); super.getSession().setAttribute("shiroUser", shiroUser); super.getSession().setAttribute("username", shiroUser.getAccount()); LogManager.me().executeLog(LogTaskFactory.loginLog(shiroUser.getId(), getIp())); ShiroKit.getSession().setAttribute("sessionFlag", true); return REDIRECT + "/"; } /** * 发送短信验证码 * * @param username * @return */ @ResponseBody @RequestMapping(value = "/base/sendSMSCode", method = RequestMethod.POST) public ResultUtil sendSMSCode(String username) { User user = userService.getByAccount(username); if (null == user) { return ResultUtil.error("无效的账号"); } if (ToolUtil.isEmpty(user.getPhone())) { return ResultUtil.error("请联系管理员完善电话号码"); } Map map = new HashMap<>(); map.put("phone", user.getPhone()); map.put("type", String.valueOf(1)); String result = HttpRequestUtil.postRequest(PushURL.send_sms_code, map); JSONObject jsonObject = JSON.parseObject(result); if (200 == jsonObject.getInteger("code")) { return ResultUtil.success(); } return ResultUtil.error(jsonObject.getString("msg")); } }