|
@@ -1,57 +1,74 @@
|
|
|
package com.backendsys.modules.system.service.impl;
|
|
|
|
|
|
-import com.backendsys.config.Kaptcha.KaptchaUtil;
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
import com.backendsys.exception.CustException;
|
|
|
import com.backendsys.modules.common.config.redis.utils.RedisUtil;
|
|
|
+import com.backendsys.modules.common.config.security.entity.SecurityUserInfo;
|
|
|
import com.backendsys.modules.common.config.security.utils.CaptchaUtil;
|
|
|
import com.backendsys.modules.common.config.security.utils.CountUtilV2;
|
|
|
import com.backendsys.modules.common.config.security.utils.HttpRequestUtil;
|
|
|
+import com.backendsys.modules.common.config.security.utils.JwtUtil;
|
|
|
import com.backendsys.modules.system.dao.SysMobileAreaDao;
|
|
|
import com.backendsys.modules.system.dao.SysUserDao;
|
|
|
+import com.backendsys.modules.system.dao.SysUserInfoDao;
|
|
|
import com.backendsys.modules.system.entity.SysAuth;
|
|
|
import com.backendsys.modules.system.entity.SysMobileArea;
|
|
|
import com.backendsys.modules.system.entity.SysUser;
|
|
|
+import com.backendsys.modules.system.entity.SysUserInfo;
|
|
|
import com.backendsys.modules.system.service.SysAuthV2Service;
|
|
|
+import com.backendsys.modules.system.service.SysUserV2Service;
|
|
|
import com.backendsys.utils.response.ResultEnum;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.google.code.kaptcha.Producer;
|
|
|
import jakarta.servlet.ServletOutputStream;
|
|
|
-import jakarta.servlet.http.HttpServletRequest;
|
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import javax.imageio.ImageIO;
|
|
|
import java.awt.image.BufferedImage;
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
import java.io.IOException;
|
|
|
+import java.util.Date;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.UUID;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
@Service
|
|
|
public class SysAuthV2ServiceImpl implements SysAuthV2Service {
|
|
|
|
|
|
- @Autowired
|
|
|
- private HttpRequestUtil httpRequestUtil;
|
|
|
@Autowired
|
|
|
private RedisUtil redisUtil;
|
|
|
@Autowired
|
|
|
+ private JwtUtil jwtUtil;
|
|
|
+ @Autowired
|
|
|
+ private HttpRequestUtil httpRequestUtil;
|
|
|
+ @Autowired
|
|
|
private CountUtilV2 countUtilV2;
|
|
|
@Autowired
|
|
|
private CaptchaUtil captchaUtil;
|
|
|
-
|
|
|
@Autowired
|
|
|
private Producer captchaProducer;
|
|
|
- @Value("${CAPTCHA_DURATION}")
|
|
|
- private Integer CAPTCHA_DURATION;
|
|
|
|
|
|
@Autowired
|
|
|
private SysUserDao sysUserDao;
|
|
|
@Autowired
|
|
|
+ private SysUserInfoDao sysUserInfoDao;
|
|
|
+ @Autowired
|
|
|
+ private SysUserV2Service sysUserV2Service;
|
|
|
+ @Autowired
|
|
|
private SysMobileAreaDao sysMobileAreaDao;
|
|
|
|
|
|
+ @Value("${CAPTCHA_DURATION}")
|
|
|
+ private Integer CAPTCHA_DURATION;
|
|
|
+ @Value("${TOKEN_DURATION_SYSTEM}")
|
|
|
+ private Integer TOKEN_DURATION_SYSTEM;
|
|
|
+
|
|
|
@Override
|
|
|
public void renderCaptcha(HttpServletResponse response) throws IOException {
|
|
|
byte[] captchaChallengeAsJpeg;
|
|
@@ -85,54 +102,92 @@ public class SysAuthV2ServiceImpl implements SysAuthV2Service {
|
|
|
return sysMobileAreaDao.selectMobileAreaList(sysMobileArea);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public Map<String, Object> login(SysAuth sysAuth) {
|
|
|
+ // [方法] 登录失败 (errMsg: 错误提示文本, username: 用户名, intercept: 是否拦截)
|
|
|
+ private void loginFail(String errMsg, String username, Boolean isIntercept) {
|
|
|
+ redisUtil.delete(httpRequestUtil.getKaptchaKey());
|
|
|
+ // 添加登录错误的冻结标记
|
|
|
+ if (isIntercept) countUtilV2.setErrorCount("login-error", username);
|
|
|
+ throw new CustException(errMsg, ResultEnum.INVALID_CREDENTIALS.getCode());
|
|
|
+ }
|
|
|
|
|
|
-// System.out.println(sysAuth);
|
|
|
-// System.out.println(httpRequestUtil.getIpAddr());
|
|
|
+ // [方法] 登录成功
|
|
|
+ private SysUserInfo loginSuccess(SysAuth sysAuth) {
|
|
|
+
|
|
|
+ // [查询] 登录的用户信息
|
|
|
+ SysUserInfo sysUserInfo = sysUserV2Service.selectUserInfo(sysAuth.getUser_id());
|
|
|
+
|
|
|
+ // 清除缓存
|
|
|
+ redisUtil.delete(httpRequestUtil.getKaptchaKey()); // 作废验证码密钥
|
|
|
+ redisUtil.delete("token:id:" + sysUserInfo.getLast_login_uuid()); // 删除旧的登录缓存 (Redis)
|
|
|
+
|
|
|
+ // 判断用户是否审核
|
|
|
+ Integer auditStatus = sysUserInfo.getAudit_status();
|
|
|
+ if (auditStatus != null && auditStatus.equals(1)) throw new CustException("请等待管理员审核");
|
|
|
+ if (auditStatus != null && auditStatus.equals(-1)) throw new CustException("审核未通过,请与客服联系");
|
|
|
+
|
|
|
+ // 判断用户是否启用
|
|
|
+ Integer status = sysUserInfo.getStatus();
|
|
|
+ if (status != null && status.equals(-1)) throw new CustException("该用户已被禁用,请与客服联系");
|
|
|
+
|
|
|
+ // 判断用户是否已删除
|
|
|
+ Integer delFlag = sysUserInfo.getDel_flag();
|
|
|
+ if (delFlag != null && delFlag.equals(1)) throw new CustException("用户状态异常,请与客服联系");
|
|
|
+
|
|
|
+ // 设置 最后一次的登录信息 (uuid, ip, 登录时间)
|
|
|
+ String uuid = String.valueOf(UUID.randomUUID());
|
|
|
+ sysUserInfo.setLast_login_uuid(uuid);
|
|
|
+ sysUserInfo.setLast_login_ip(httpRequestUtil.getIpAddr());
|
|
|
+ sysUserInfo.setLast_login_time(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
|
|
|
+ sysUserInfoDao.updateById(sysUserInfo);
|
|
|
+
|
|
|
+ // 设置 Token 过期时间
|
|
|
+ Integer isRemember = sysAuth.getIs_remember();
|
|
|
+ Integer tokenDuration = (isRemember != null && isRemember.equals(1)) ? TOKEN_DURATION_SYSTEM * 7 : TOKEN_DURATION_SYSTEM;
|
|
|
+ Date tokenExpiration = new Date((new Date()).getTime() + tokenDuration);
|
|
|
+ sysUserInfo.setToken_expiration(DateUtil.format(tokenExpiration, "yyyy-MM-dd HH:mm:ss"));
|
|
|
+
|
|
|
+ // 生成 Token
|
|
|
+ SecurityUserInfo securityUserInfo = JSONUtil.toBean(JSONUtil.parseObj(sysUserInfo), SecurityUserInfo.class);
|
|
|
+ String token = jwtUtil.createJwtToken(securityUserInfo);
|
|
|
+ String tokenRedisKey = "token:id:" + uuid;
|
|
|
+ redisUtil.setCacheObject(tokenRedisKey, token, tokenDuration, TimeUnit.MILLISECONDS);
|
|
|
+ sysUserInfo.setToken(token);
|
|
|
+
|
|
|
+ return sysUserInfo;
|
|
|
+ }
|
|
|
|
|
|
- String username = sysAuth.getUsername();
|
|
|
- String password = sysAuth.getPassword();
|
|
|
- String captcha = sysAuth.getCaptcha();
|
|
|
+ @Override
|
|
|
+ @Transactional
|
|
|
+ public SysUserInfo login(SysAuth sysAuth) {
|
|
|
|
|
|
- // 判断是否处于 5次的错误状态
|
|
|
+ // 判断是否处于登录错误的冻结状态 (2分钟内错误5次,则出现冻结提示)
|
|
|
countUtilV2.checkErrorStatus("login-error", sysAuth.getUsername());
|
|
|
|
|
|
// [Method] 判断验证码是否正确 (RedisKey: (ua + ip))
|
|
|
- String captchaRedisKey = httpRequestUtil.getKaptchaKey();
|
|
|
- if (!captchaUtil.isCaptchaValid(captcha, captchaRedisKey)) {
|
|
|
- redisUtil.delete(captchaRedisKey);
|
|
|
- throw new CustException("验证码错误", ResultEnum.INVALID_CREDENTIALS.getCode());
|
|
|
+ if (!captchaUtil.isCaptchaValid(sysAuth.getCaptcha(), httpRequestUtil.getKaptchaKey())) {
|
|
|
+ loginFail("验证码错误", sysAuth.getUsername(), false);
|
|
|
+ return null;
|
|
|
}
|
|
|
|
|
|
// [Method] 判断 用户 是否存在 && 密码是否正确
|
|
|
- SysUser sysUser = sysUserDao.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
|
|
|
+ SysUser sysUser = sysUserDao.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, sysAuth.getUsername()));
|
|
|
if (sysUser == null) {
|
|
|
- redisUtil.delete(captchaRedisKey);
|
|
|
- // 添加错误标记 (2分钟内错误5次,则出现冻结提示)
|
|
|
- countUtilV2.setErrorCount("login-error", username);
|
|
|
- throw new CustException("用户名或密码错误", ResultEnum.INVALID_CREDENTIALS.getCode());
|
|
|
+ // [登录失败] 用户不存在
|
|
|
+ loginFail("用户名或密码错误", sysAuth.getUsername(), true);
|
|
|
+ return null;
|
|
|
+ } else {
|
|
|
+
|
|
|
+ // [登录失败] 密码不正确
|
|
|
+ BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
|
|
|
+ if (!encoder.matches(sysAuth.getPassword(), sysUser.getPassword())) {
|
|
|
+ loginFail("用户名或密码错误", sysAuth.getUsername(), true);
|
|
|
+ }
|
|
|
+
|
|
|
+ // [登录成功]
|
|
|
+ sysAuth.setUser_id(sysUser.getId());
|
|
|
+ return loginSuccess(sysAuth);
|
|
|
}
|
|
|
- System.out.println(sysUser);
|
|
|
-
|
|
|
-// Map<String, Object> sysUserSimple = sysUserMapper.queryUserByIdOrName(null, username, null, null);
|
|
|
-// if (sysUserSimple != null) {
|
|
|
-// sysUserDTO.setUser_id((Long) sysUserSimple.get("id"));
|
|
|
-// }
|
|
|
-// if (!(sysUserSimple != null && isUserPasswordValid(sysUserSimple, password))) {
|
|
|
-// stringRedisTemplate.delete(captchaRedisKey);
|
|
|
-// // 添加错误标记 (2分钟内错误5次,则出现提示)
|
|
|
-// countUtil.setErrorCount("login-error", username);
|
|
|
-// throw new CustException("用户名或密码错误", ResultEnum.INVALID_CREDENTIALS.getCode());
|
|
|
-// }
|
|
|
-//
|
|
|
-// // 1.作废验证码密钥
|
|
|
-// stringRedisTemplate.delete(captchaRedisKey);
|
|
|
-//
|
|
|
-// // [登录成功]
|
|
|
-// Map<String, Object> result = loginSuccess(request, sysUserDTO);
|
|
|
-
|
|
|
- return null;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
}
|