目 录CONTENT

文章目录

登录日志切面

Jinty
2024-07-20 / 0 评论 / 0 点赞 / 28 阅读 / 4985 字

登录日志切面实现

基本思路

对标注了登录日志注解的方法进行切面处理,在登录接口成功后记录账号的登录成功日志,包括登录IP、时间、使用客户端等信息。

登录日志表设计

DROP TABLE IF EXISTS `account_login_log`;
CREATE TABLE `account_login_log`  (
  `id` bigint NOT NULL COMMENT '主键ID',
  `create_by` bigint NULL DEFAULT NULL COMMENT '创建者',
  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
  `update_by` bigint NULL DEFAULT NULL COMMENT '最后更新者',
  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
  `account_id` bigint NOT NULL COMMENT '登录账号ID',
  `login_time` datetime NULL DEFAULT NULL COMMENT '登录时间',
  `login_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '登录方式,如用户名密码登录、短信验证码登录等登录IP地址',
  `login_ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '登录IP地址',
  `login_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '登录地点',
  `login_device` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '登录设备信息',
  `browser` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户登录时使用的浏览器信息',
  `operating_system` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户登录时使用的操作系统信息',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '账号登录日志' ROW_FORMAT = Dynamic;

登录日志注解定义

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LoginLog {
}

登录日志切面定义

@Aspect
@Component
@RequiredArgsConstructor
public class LoginLogAspect {
    private final AccountLoginLogService accountLoginLogService;

    @Pointcut(value = "@annotation(loginLog)")
    public void pointcut(LoginLog loginLog) {
    }

    @AfterReturning("pointcut(loginLog)")
    public void afterReturningAdvice(JoinPoint joinPoint, LoginLog loginLog) {
        Long loginId = StpUtil.getLoginId(-1L);
        accountLoginLogService.asyncSaveLog(loginId, DateUtil.date(), RequestUtils.getRequest());
    }
}

登录日志保存服务实现

import cn.com.jcoo.system.entity.AccountLoginLog;
import cn.com.jcoo.system.mapper.AccountLoginLogMapper;
import cn.com.jcoo.util.RequestUtils;
import cn.hutool.http.useragent.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

@Slf4j
@RequiredArgsConstructor
@Service
public class AccountLoginLogService extends ServiceImpl<AccountLoginLogMapper, AccountLoginLog> {

    @Async
    public void asyncSaveLog(Long accountId, Date loginTime, HttpServletRequest request) {
        AccountLoginLog accountLoginLog = new AccountLoginLog();
        accountLoginLog.setAccountId(accountId);
        accountLoginLog.setLoginTime(loginTime);
		
        String requestIP = RequestUtils.getRequestIP(request);
        String userAgentHeader = request.getHeader(HttpHeaders.USER_AGENT);

        UserAgent userAgent = UserAgentUtil.parse(userAgentHeader);
        Platform platform = userAgent.getPlatform();
        Browser browser = userAgent.getBrowser();
        OS os = userAgent.getOs();
        String osName = os.getName().split(" ")[0];
        String osVersion = os.getVersion(userAgentHeader);

        accountLoginLog.setLoginIp(requestIP);
        accountLoginLog.setLoginDevice(platform.getName());
        accountLoginLog.setBrowser(browser.getName());
        accountLoginLog.setOperatingSystem(osName + " " + osVersion);
        this.save(accountLoginLog);
    }
}

使用示例及效果展示

对登录接口中标注登录日志注解:

@ApiOperationSupport(author = "jinty")
@LoginLog
@Operation(summary = "登录")
@PostMapping("/login")
ApiRet<LoginUser> login(@Valid @RequestBody LoginParam param) {
	...
}

0

评论区