From 083dac77e1ef5e6bc04ce09fe03c31258e2ed93a Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 18 Jan 2021 00:23:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E5=85=A5=E7=99=BB=E9=99=86=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../monitor/SysLogininforController.java | 11 ++-- .../operatelog/core/aop/OperateLogAspect.java | 8 +-- .../logger/SysLoginLogController.java | 4 ++ .../logger/vo/loginlog/SysLoginLogBaseVO.java | 12 ++-- .../vo/loginlog/SysLoginLogCreateReqVO.java | 3 +- .../convert/logger/SysLoginLogConvert.java | 15 +++++ .../mysql/dao/logger/SysLoginLogMapper.java | 9 +++ .../dataobject/logger/SysLoginLogDO.java | 28 +++++---- .../system/enums/SysErrorCodeConstants.java | 2 + .../enums/logger/SysLoginLogTypeEnum.java | 21 +++++++ .../enums/logger/SysLoginResultEnum.java | 6 ++ .../service/auth/impl/SysAuthServiceImpl.java | 63 +++++++++++++------ .../service/common/SysCaptchaService.java | 20 ++++++ .../common/impl/SysCaptchaServiceImpl.java | 10 +++ .../service/logger/SysLoginLogService.java | 17 +++++ .../logger/impl/SysLoginLogServiceImpl.java | 27 ++++++++ .../dashboard/util/servlet/ServletUtils.java | 32 ++++++++++ 17 files changed, 236 insertions(+), 52 deletions(-) create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/SysLoginLogController.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/convert/logger/SysLoginLogConvert.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/logger/SysLoginLogMapper.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/enums/logger/SysLoginLogTypeEnum.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/service/logger/SysLoginLogService.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/service/logger/impl/SysLoginLogServiceImpl.java diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java index 81650592f..6146f34ad 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java @@ -1,6 +1,7 @@ package com.ruoyi.web.controller.monitor; import java.util.List; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.DeleteMapping; @@ -24,15 +25,14 @@ import com.ruoyi.system.service.ISysLogininforService; */ @RestController @RequestMapping("/monitor/logininfor") -public class SysLogininforController extends BaseController -{ +public class SysLogininforController extends BaseController { + @Autowired private ISysLogininforService logininforService; @PreAuthorize("@ss.hasPermi('monitor:logininfor:list')") @GetMapping("/list") - public TableDataInfo list(SysLogininfor logininfor) - { + public TableDataInfo list(SysLogininfor logininfor) { startPage(); List list = logininforService.selectLogininforList(logininfor); return getDataTable(list); @@ -41,8 +41,7 @@ public class SysLogininforController extends BaseController @Log(title = "登录日志", businessType = BusinessType.EXPORT) @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')") @GetMapping("/export") - public AjaxResult export(SysLogininfor logininfor) - { + public AjaxResult export(SysLogininfor logininfor) { List list = logininforService.selectLogininforList(logininfor); ExcelUtil util = new ExcelUtil(SysLogininfor.class); return util.exportExcel(list, "登录日志"); diff --git a/src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/aop/OperateLogAspect.java b/src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/aop/OperateLogAspect.java index 54308a767..cd7c0e22d 100644 --- a/src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/aop/OperateLogAspect.java +++ b/src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/aop/OperateLogAspect.java @@ -24,9 +24,6 @@ import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.context.request.RequestAttributes; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; @@ -196,11 +193,10 @@ public class OperateLogAspect { private static void fillRequestFields(SysOperateLogCreateReqVO operateLogVO) { // 获得 Request 对象 - RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); - if (!(requestAttributes instanceof ServletRequestAttributes)) { + HttpServletRequest request = ServletUtils.getRequest(); + if (request == null) { return; } - HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); // 补全请求信息 operateLogVO.setRequestMethod(request.getMethod()); operateLogVO.setRequestUrl(request.getRequestURI()); diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/SysLoginLogController.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/SysLoginLogController.java new file mode 100644 index 000000000..65fba768d --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/SysLoginLogController.java @@ -0,0 +1,4 @@ +package cn.iocoder.dashboard.modules.system.controller.logger; + +public class SysLoginLogController { +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/loginlog/SysLoginLogBaseVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/loginlog/SysLoginLogBaseVO.java index 66ae5b6c5..c5dd34ea9 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/loginlog/SysLoginLogBaseVO.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/loginlog/SysLoginLogBaseVO.java @@ -15,27 +15,23 @@ import javax.validation.constraints.Size; @Data public class SysLoginLogBaseVO { + @ApiModelProperty(value = "日志类型", required = true, example = "1", notes = "参见 SysLoginLogTypeEnum 枚举类") + @NotNull(message = "日志类型不能为空") + private Integer logType; + @ApiModelProperty(value = "链路追踪编号", required = true, example = "89aca178-a370-411c-ae02-3f0d672be4ab") @NotEmpty(message = "链路追踪编号不能为空") private String traceId; - @ApiModelProperty(value = "用户编号", required = true, example = "1024") - @NotNull(message = "用户编号不能为空") - private Long userId; - @ApiModelProperty(value = "用户账号", required = true, example = "yudao") @NotBlank(message = "用户账号不能为空") @Size(max = 30, message = "用户账号长度不能超过30个字符") private String username; - @ApiModelProperty(value = "登陆结果", required = true, example = "1", notes = "参见 SysLoginResultEnum 枚举类") @NotNull(message = "登陆结果不能为空") private Integer result; - @ApiModelProperty(value = "操作明细", example = "修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。") - private String content; - @ApiModelProperty(value = "用户 IP", required = true, example = "127.0.0.1") @NotEmpty(message = "用户 IP 不能为空") private String userIp; diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/loginlog/SysLoginLogCreateReqVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/loginlog/SysLoginLogCreateReqVO.java index bc3ed6655..78a0c4541 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/loginlog/SysLoginLogCreateReqVO.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/loginlog/SysLoginLogCreateReqVO.java @@ -1,6 +1,5 @@ package cn.iocoder.dashboard.modules.system.controller.logger.vo.loginlog; -import cn.iocoder.dashboard.modules.system.controller.logger.vo.operatelog.SysOperateLogCreateReqVO; import io.swagger.annotations.ApiModel; import lombok.Data; import lombok.EqualsAndHashCode; @@ -11,5 +10,5 @@ import lombok.ToString; @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class SysLoginLogCreateReqVO extends SysOperateLogCreateReqVO { +public class SysLoginLogCreateReqVO extends SysLoginLogBaseVO { } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/convert/logger/SysLoginLogConvert.java b/src/main/java/cn/iocoder/dashboard/modules/system/convert/logger/SysLoginLogConvert.java new file mode 100644 index 000000000..301fff469 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/system/convert/logger/SysLoginLogConvert.java @@ -0,0 +1,15 @@ +package cn.iocoder.dashboard.modules.system.convert.logger; + +import cn.iocoder.dashboard.modules.system.controller.logger.vo.loginlog.SysLoginLogCreateReqVO; +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysLoginLogDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface SysLoginLogConvert { + + SysLoginLogConvert INSTANCE = Mappers.getMapper(SysLoginLogConvert.class); + + SysLoginLogDO convert(SysLoginLogCreateReqVO bean); + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/logger/SysLoginLogMapper.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/logger/SysLoginLogMapper.java new file mode 100644 index 000000000..5f0b0904c --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/logger/SysLoginLogMapper.java @@ -0,0 +1,9 @@ +package cn.iocoder.dashboard.modules.system.dal.mysql.dao.logger; + +import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysLoginLogDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface SysLoginLogMapper extends BaseMapperX { +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/logger/SysLoginLogDO.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/logger/SysLoginLogDO.java index da8e5ca00..3ef1c6b48 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/logger/SysLoginLogDO.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/logger/SysLoginLogDO.java @@ -1,32 +1,40 @@ package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger; import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; +import cn.iocoder.dashboard.modules.system.enums.logger.SysLoginLogTypeEnum; import cn.iocoder.dashboard.modules.system.enums.logger.SysLoginResultEnum; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; /** - * 系统访问记录表 + * 登陆日志表 + * + * 注意,包括登陆和登出两种行为 * * @author ruoyi */ -@TableName("用户登陆日志") +@TableName("sys_login_log") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) public class SysLoginLogDO extends BaseDO { /** * 日志主键 */ private Long id; + /** + * 日志类型 + * + * 枚举 {@link SysLoginLogTypeEnum} + */ + private Integer logType; /** * 链路追踪编号 */ private String traceId; - /** - * 用户编号 - * - * 外键 {@link SysUserDO#getId()} - */ - private Long userId; /** * 用户账号 * @@ -39,12 +47,10 @@ public class SysLoginLogDO extends BaseDO { * 枚举 {@link SysLoginResultEnum} */ private Integer result; - /** * 用户 IP */ private String userIp; - /** * 浏览器 UA */ diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java b/src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java index 0bd0a4a56..dafa09faa 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java @@ -13,6 +13,8 @@ public interface SysErrorCodeConstants { ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1002000000, "登录失败,账号密码不正确"); ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1002000001, "登录失败,账号被禁用"); ErrorCode AUTH_LOGIN_FAIL_UNKNOWN = new ErrorCode(1002000002, "登录失败"); // 登陆失败的兜底,位置原因 + ErrorCode AUTH_LOGIN_CAPTCHA_NOT_FOUND = new ErrorCode(1002000003, "验证码不存在"); + ErrorCode AUTH_LOGIN_CAPTCHA_CODE_ERROR = new ErrorCode(1002000004, "验证码不正确"); // ========== TOKEN 模块 1002001000 ========== ErrorCode TOKEN_EXPIRED = new ErrorCode(1002001000, "Token 已经过期"); diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/enums/logger/SysLoginLogTypeEnum.java b/src/main/java/cn/iocoder/dashboard/modules/system/enums/logger/SysLoginLogTypeEnum.java new file mode 100644 index 000000000..9249dd1e7 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/system/enums/logger/SysLoginLogTypeEnum.java @@ -0,0 +1,21 @@ +package cn.iocoder.dashboard.modules.system.enums.logger; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 登陆日志的类型枚举 + */ +@Getter +@AllArgsConstructor +public enum SysLoginLogTypeEnum { + + LOGIN(1), + LOGOUT(2); + + /** + * 日志类型 + */ + private final Integer type; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/enums/logger/SysLoginResultEnum.java b/src/main/java/cn/iocoder/dashboard/modules/system/enums/logger/SysLoginResultEnum.java index cb66f6177..4a26a7243 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/enums/logger/SysLoginResultEnum.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/enums/logger/SysLoginResultEnum.java @@ -11,6 +11,12 @@ import lombok.Getter; public enum SysLoginResultEnum { SUCCESS(0), // 成功 + BAD_CREDENTIALS(10), // 账号或密码不正确 + USER_DISABLED(20), // 账号或密码不正确 + CAPTCHA_NOT_FOUND(30), // 验证码不存在 + CAPTCHA_CODE_ERROR(31), // 验证码不正确 + + UNKNOWN_ERROR(100), // 未知异常 ; /** diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java index 825022001..ce44b0a1e 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/auth/impl/SysAuthServiceImpl.java @@ -3,16 +3,24 @@ package cn.iocoder.dashboard.modules.system.service.auth.impl; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.dashboard.common.enums.CommonStatusEnum; +import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil; import cn.iocoder.dashboard.framework.security.config.SecurityProperties; import cn.iocoder.dashboard.framework.security.core.LoginUser; +import cn.iocoder.dashboard.framework.tracer.core.util.TracerUtils; +import cn.iocoder.dashboard.modules.system.controller.logger.vo.loginlog.SysLoginLogCreateReqVO; import cn.iocoder.dashboard.modules.system.convert.auth.SysAuthConvert; import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; import cn.iocoder.dashboard.modules.system.dal.redis.dao.auth.SysLoginUserRedisDAO; +import cn.iocoder.dashboard.modules.system.enums.logger.SysLoginLogTypeEnum; +import cn.iocoder.dashboard.modules.system.enums.logger.SysLoginResultEnum; import cn.iocoder.dashboard.modules.system.service.auth.SysAuthService; import cn.iocoder.dashboard.modules.system.service.auth.SysTokenService; +import cn.iocoder.dashboard.modules.system.service.common.SysCaptchaService; +import cn.iocoder.dashboard.modules.system.service.logger.SysLoginLogService; import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; import cn.iocoder.dashboard.modules.system.service.user.SysUserService; import cn.iocoder.dashboard.util.date.DateUtils; +import cn.iocoder.dashboard.util.servlet.ServletUtils; import io.jsonwebtoken.Claims; import io.jsonwebtoken.JwtException; import lombok.extern.slf4j.Slf4j; @@ -55,6 +63,10 @@ public class SysAuthServiceImpl implements SysAuthService { private SysUserService userService; @Resource private SysPermissionService permissionService; + @Resource + private SysCaptchaService captchaService; + @Resource + private SysLoginLogService loginLogService; @Resource private SysLoginUserRedisDAO loginUserRedisDAO; @@ -87,7 +99,7 @@ public class SysAuthServiceImpl implements SysAuthService { @Override public String login(String username, String password, String captchaUUID, String captchaCode) { // 判断验证码是否正确 - this.verifyCaptcha(captchaUUID, captchaCode); + this.verifyCaptcha(username, captchaUUID, captchaCode); // 使用账号密码,进行登陆。 LoginUser loginUser = this.login0(username, password); @@ -102,18 +114,20 @@ public class SysAuthServiceImpl implements SysAuthService { return tokenService.createToken(sessionId); } - private void verifyCaptcha(String captchaUUID, String captchaCode) { - // String verifyKey = Constants.CAPTCHA_CODE_KEY + captchaUUID; -// String captcha = redisCache.getCacheObject(verifyKey); -// redisCache.deleteObject(verifyKey); -// if (captcha == null) { -// AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"))); -// throw new CaptchaExpireException(); -// } -// if (!code.equalsIgnoreCase(captcha)) { -// AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); -// throw new CaptchaException(); -// } + private void verifyCaptcha(String username, String captchaUUID, String captchaCode) { + String code = captchaService.getCaptchaCode(captchaUUID); + // 验证码不存在 + if (code == null) { + this.createLoginLog(username, SysLoginResultEnum.CAPTCHA_NOT_FOUND); + throw ServiceExceptionUtil.exception(AUTH_LOGIN_CAPTCHA_NOT_FOUND); + } + // 验证码不正确 + if (!code.equals(captchaCode)) { + this.createLoginLog(username, SysLoginResultEnum.CAPTCHA_CODE_ERROR); + throw ServiceExceptionUtil.exception(AUTH_LOGIN_CAPTCHA_CODE_ERROR); + } + // 正确,所以要删除下验证码 + captchaService.deleteCaptchaCode(captchaUUID); } private LoginUser login0(String username, String password) { @@ -124,22 +138,33 @@ public class SysAuthServiceImpl implements SysAuthService { // 在其内部,会调用到 loadUserByUsername 方法,获取 User 信息 authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password)); } catch (BadCredentialsException badCredentialsException) { - // TODO 日志优化 -// AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + this.createLoginLog(username, SysLoginResultEnum.BAD_CREDENTIALS); throw exception(AUTH_LOGIN_BAD_CREDENTIALS); } catch (DisabledException disabledException) { - // TODO 日志优化 + this.createLoginLog(username, SysLoginResultEnum.USER_DISABLED); throw exception(AUTH_LOGIN_USER_DISABLED); } catch (AuthenticationException authenticationException) { - // TODO 日志优化 + log.error("[login0][username({}) 发生未知异常]", username, authenticationException); + this.createLoginLog(username, SysLoginResultEnum.UNKNOWN_ERROR); throw exception(AUTH_LOGIN_FAIL_UNKNOWN); } - // TODO 需要优化 -// AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); + // 登陆成功 Assert.notNull(authentication.getPrincipal(), "Principal 不会为空"); + this.createLoginLog(username, SysLoginResultEnum.SUCCESS); return (LoginUser) authentication.getPrincipal(); } + private void createLoginLog(String username, SysLoginResultEnum loginResult) { + SysLoginLogCreateReqVO reqVO = new SysLoginLogCreateReqVO(); + reqVO.setLogType(SysLoginLogTypeEnum.LOGIN.getType()); + reqVO.setTraceId(TracerUtils.getTraceId()); + reqVO.setUsername(username); + reqVO.setUserAgent(ServletUtils.getUserAgent()); + reqVO.setUserIp(ServletUtils.getClientIP()); + reqVO.setResult(loginResult.getResult()); + loginLogService.createLoginLog(reqVO); + } + /** * 获得 User 拥有的角色编号数组 * diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/common/SysCaptchaService.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/common/SysCaptchaService.java index e7c26c2ca..a86b406f8 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/common/SysCaptchaService.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/common/SysCaptchaService.java @@ -7,6 +7,26 @@ import cn.iocoder.dashboard.modules.system.controller.common.vo.SysCaptchaImageR */ public interface SysCaptchaService { + /** + * 获得验证码图片 + * + * @return 验证码图片 + */ SysCaptchaImageRespVO getCaptchaImage(); + /** + * 获得 uuid 对应的验证码 + * + * @param uuid 验证码编号 + * @return 验证码 + */ + String getCaptchaCode(String uuid); + + /** + * 删除 uuid 对应的验证码 + * + * @param uuid 验证码编号 + */ + void deleteCaptchaCode(String uuid); + } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/common/impl/SysCaptchaServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/common/impl/SysCaptchaServiceImpl.java index 856f50b5c..b44c7390e 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/common/impl/SysCaptchaServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/common/impl/SysCaptchaServiceImpl.java @@ -35,4 +35,14 @@ public class SysCaptchaServiceImpl implements SysCaptchaService { return SysCaptchaConvert.INSTANCE.convert(uuid, captcha); } + @Override + public String getCaptchaCode(String uuid) { + return captchaRedisDAO.get(uuid); + } + + @Override + public void deleteCaptchaCode(String uuid) { + captchaRedisDAO.delete(uuid); + } + } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/logger/SysLoginLogService.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/logger/SysLoginLogService.java new file mode 100644 index 000000000..adda74456 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/logger/SysLoginLogService.java @@ -0,0 +1,17 @@ +package cn.iocoder.dashboard.modules.system.service.logger; + +import cn.iocoder.dashboard.modules.system.controller.logger.vo.loginlog.SysLoginLogCreateReqVO; + +/** + * 登陆日志 Service 接口 + */ +public interface SysLoginLogService { + + /** + * 创建登陆日志 + * + * @param reqVO 日志信息 + */ + void createLoginLog(SysLoginLogCreateReqVO reqVO); + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/logger/impl/SysLoginLogServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/logger/impl/SysLoginLogServiceImpl.java new file mode 100644 index 000000000..36c41e31a --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/logger/impl/SysLoginLogServiceImpl.java @@ -0,0 +1,27 @@ +package cn.iocoder.dashboard.modules.system.service.logger.impl; + +import cn.iocoder.dashboard.modules.system.controller.logger.vo.loginlog.SysLoginLogCreateReqVO; +import cn.iocoder.dashboard.modules.system.convert.logger.SysLoginLogConvert; +import cn.iocoder.dashboard.modules.system.dal.mysql.dao.logger.SysLoginLogMapper; +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysLoginLogDO; +import cn.iocoder.dashboard.modules.system.service.logger.SysLoginLogService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 登陆日志 Service 实现 + */ +@Service +public class SysLoginLogServiceImpl implements SysLoginLogService { + + @Resource + private SysLoginLogMapper loginLogMapper; + + @Override + public void createLoginLog(SysLoginLogCreateReqVO reqVO) { + SysLoginLogDO loginLog = SysLoginLogConvert.INSTANCE.convert(reqVO); + loginLogMapper.insert(loginLog); + } + +} diff --git a/src/main/java/cn/iocoder/dashboard/util/servlet/ServletUtils.java b/src/main/java/cn/iocoder/dashboard/util/servlet/ServletUtils.java index ef4a72371..ae9f61db5 100644 --- a/src/main/java/cn/iocoder/dashboard/util/servlet/ServletUtils.java +++ b/src/main/java/cn/iocoder/dashboard/util/servlet/ServletUtils.java @@ -4,6 +4,9 @@ import cn.hutool.core.io.IoUtil; import cn.hutool.extra.servlet.ServletUtil; import com.alibaba.fastjson.JSON; import org.springframework.http.MediaType; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -54,4 +57,33 @@ public class ServletUtils { return ua != null ? ua : ""; } + /** + * 获得请求 + * + * @return HttpServletRequest + */ + public static HttpServletRequest getRequest() { + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + if (!(requestAttributes instanceof ServletRequestAttributes)) { + return null; + } + return ((ServletRequestAttributes) requestAttributes).getRequest(); + } + + public static String getUserAgent() { + HttpServletRequest request = getRequest(); + if (request == null) { + return null; + } + return getUserAgent(request); + } + + public static String getClientIP() { + HttpServletRequest request = getRequest(); + if (request == null) { + return null; + } + return ServletUtil.getClientIP(request); + } + }