package com.monkeylessey.controller.system; import com.fasterxml.jackson.core.JsonProcessingException; import com.monkeylessey.constant.RedisKeyPrefixConstants; import com.monkeylessey.sys.domain.vo.LoginUser; import com.monkeylessey.sys.domain.form.LoginForm; import com.monkeylessey.sys.domain.vo.SysUserVO; import com.monkeylessey.exception.CaptchaErrorException; import com.monkeylessey.response.Result; import com.monkeylessey.sys.service.SysUserService; import com.monkeylessey.framework.utils.RedisUtil; import com.monkeylessey.framework.utils.TokenUtil; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; /** * @author xp * @data 2023/4/3 */ @RestController @RequiredArgsConstructor public class LoginController { private final RedisUtil redisUtil; private final TokenUtil tokenUtil; private final SysUserService userService; private final AuthenticationManager authenticationManager; @PostMapping("/xpstart/login") public Result login(@RequestBody LoginForm form, HttpServletResponse response) throws JsonProcessingException { // 验证码校验 String redisCaptcha = redisUtil.getValue(RedisKeyPrefixConstants.CAPTCHA + form.getCaptchaId(), String.class); if (StringUtils.isEmpty(redisCaptcha)) { // 验证码过期异常 throw new CaptchaErrorException("验证码已过期"); } else if (!redisCaptcha.equalsIgnoreCase(form.getCaptcha())) { // 验证码错误异常 throw new CaptchaErrorException("验证码错误"); } // 验证码正确,删除redis中的验证码 redisUtil.deleteKey(RedisKeyPrefixConstants.CAPTCHA + form.getCaptchaId()); UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(form.getUsername(), form.getPassword()); SecurityContextHolder.getContext().setAuthentication(authenticationToken); // 调用认证流程 Authentication authentication = authenticationManager.authenticate(authenticationToken); LoginUser loginUser = (LoginUser) authentication.getPrincipal(); // 生成token String token = tokenUtil.createToken(loginUser); Result success = Result.ok("登录成功"); // 用户名查找用户可使用的菜单 success.data(userService.getMenus(authentication.getName())); // 返回用户基本信息 SysUserVO user = loginUser.getUser(); user.setPassword(""); user.setPhoneNumber(""); success.put("userInfo", user); // 将token放入响应头 // 因为默认只有7种简单响应头可以暴露出去,要使用自定义响应头,需添加如下两行代码 response.addHeader("Access-Control-Expose-Headers", tokenUtil.getHeader()); response.addHeader(tokenUtil.getHeader(), token); response.setStatus(HttpStatus.OK.value()); response.setContentType(MediaType.APPLICATION_JSON_VALUE); return success; } @GetMapping("/auth") public Result getAuth(@RequestParam String username) { return Result.ok().data(userService.getMenus(username)); } }