package jnpf.listener; import cn.dev33.satoken.listener.SaTokenListenerForSimple; import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.parameter.SaLoginParameter; import jnpf.base.UserInfo; import jnpf.base.model.logmodel.LogoutReason; import jnpf.message.SentMessageApi; import jnpf.permission.UserApi; import jnpf.permission.entity.UserEntity; import jnpf.permission.model.user.UserUpdateModel; import jnpf.service.LoginSessionLogRecorder; import jnpf.util.DateUtil; import jnpf.util.IpUtil; import jnpf.util.UserProvider; import jnpf.utils.LoginHolder; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; /** * Sa-Token lifecycle listener shared by aggregated and microservice deployments. */ @Component @Slf4j @RequiredArgsConstructor public class LoginListener extends SaTokenListenerForSimple { private final SentMessageApi messageApi; private final UserApi userApi; private final LoginSessionLogRecorder loginSessionLogRecorder; @Override public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginParameter loginModel) { println("用户登录:{}, 设备:{}, TOKEN:{}", loginId, loginType, tokenValue); UserInfo userInfo = UserProvider.getUser(); // Temp users participate in session logs, but do not update normal account statistics. if (!UserProvider.isTempUser(userInfo)) { UserEntity entity = LoginHolder.getUserEntity(); if (entity == null) { return; } entity.setLogErrorCount(0); entity.setUnlockTime(null); entity.setEnabledMark(1); entity.setDisableTime(null); entity.setPrevLogIp(IpUtil.getIpAddr()); entity.setPrevLogTime(DateUtil.getNowDate()); entity.setLastLogIp(IpUtil.getIpAddr()); entity.setLastLogTime(DateUtil.getNowDate()); entity.setLogSuccessCount(entity.getLogSuccessCount() != null ? entity.getLogSuccessCount() + 1 : 1); userApi.updateById(new UserUpdateModel(entity, userInfo.getTenantId())); } } @Override public void doLogout(String loginType, Object loginId, String tokenValue) { println("用户退出:{}, 设备:{}, TOKEN:{}", loginId, loginType, tokenValue); loginSessionLogRecorder.close(tokenValue, getUserInfo(tokenValue), LogoutReason.MANUAL, "主动退出"); } @Override public void doKickout(String loginType, Object loginId, String tokenValue) { println("用户踢出:{}, 设备:{}, TOKEN:{}", loginId, loginType, tokenValue); loginSessionLogRecorder.close(tokenValue, getUserInfo(tokenValue), LogoutReason.KICKOUT, "强制下线"); messageApi.logoutWebsocketByToken(tokenValue, null); SaSession session = safeTokenSession(tokenValue); if (session != null) { session.logout(); } } @Override public void doReplaced(String loginType, Object loginId, String tokenValue) { println("用户顶替:{}, 设备:{}, TOKEN:{}", loginId, loginType, tokenValue); loginSessionLogRecorder.close(tokenValue, getUserInfo(tokenValue), LogoutReason.REPLACED, "登录顶替"); messageApi.logoutWebsocketByToken(tokenValue, null); SaSession session = safeTokenSession(tokenValue); if (session != null) { session.logout(); } } private UserInfo getUserInfo(String tokenValue) { SaSession session = safeTokenSession(tokenValue); return session == null ? null : (UserInfo) session.get("userInfo"); } private SaSession safeTokenSession(String tokenValue) { try { return StpUtil.getTokenSessionByToken(tokenValue); } catch (Exception e) { return null; } } private void println(String text, Object... params) { if (log.isDebugEnabled()) { log.debug(text, params); } } }