mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-03-31 13:03:22 +08:00
update [重大改动] 将 framework 与 system 模块 解耦
This commit is contained in:
@@ -1,15 +1,24 @@
|
||||
package com.ruoyi.system.service.impl;
|
||||
|
||||
import cn.hutool.http.useragent.UserAgent;
|
||||
import cn.hutool.http.useragent.UserAgentUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.core.service.LogininforService;
|
||||
import com.ruoyi.common.utils.PageUtils;
|
||||
import com.ruoyi.common.utils.ServletUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.ip.AddressUtils;
|
||||
import com.ruoyi.system.domain.SysLogininfor;
|
||||
import com.ruoyi.system.mapper.SysLogininforMapper;
|
||||
import com.ruoyi.system.service.ISysLogininforService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@@ -20,8 +29,62 @@ import java.util.Map;
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SysLogininforServiceImpl extends ServicePlusImpl<SysLogininforMapper, SysLogininfor, SysLogininfor> implements ISysLogininforService {
|
||||
public class SysLogininforServiceImpl extends ServicePlusImpl<SysLogininforMapper, SysLogininfor, SysLogininfor> implements ISysLogininforService, LogininforService {
|
||||
|
||||
/**
|
||||
* 记录登录信息
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param status 状态
|
||||
* @param message 消息
|
||||
* @param args 列表
|
||||
*/
|
||||
@Async
|
||||
@Override
|
||||
public void recordLogininfor(final String username, final String status, final String message,
|
||||
HttpServletRequest request, final Object... args) {
|
||||
final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
|
||||
final String ip = ServletUtils.getClientIP(request);
|
||||
|
||||
String address = AddressUtils.getRealAddressByIP(ip);
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append(getBlock(ip));
|
||||
s.append(address);
|
||||
s.append(getBlock(username));
|
||||
s.append(getBlock(status));
|
||||
s.append(getBlock(message));
|
||||
// 打印信息到日志
|
||||
log.info(s.toString(), args);
|
||||
// 获取客户端操作系统
|
||||
String os = userAgent.getOs().getName();
|
||||
// 获取客户端浏览器
|
||||
String browser = userAgent.getBrowser().getName();
|
||||
// 封装对象
|
||||
SysLogininfor logininfor = new SysLogininfor();
|
||||
logininfor.setUserName(username);
|
||||
logininfor.setIpaddr(ip);
|
||||
logininfor.setLoginLocation(address);
|
||||
logininfor.setBrowser(browser);
|
||||
logininfor.setOs(os);
|
||||
logininfor.setMsg(message);
|
||||
// 日志状态
|
||||
if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
|
||||
logininfor.setStatus(Constants.SUCCESS);
|
||||
} else if (Constants.LOGIN_FAIL.equals(status)) {
|
||||
logininfor.setStatus(Constants.FAIL);
|
||||
}
|
||||
// 插入数据
|
||||
insertLogininfor(logininfor);
|
||||
}
|
||||
|
||||
private String getBlock(Object msg) {
|
||||
if (msg == null) {
|
||||
msg = "";
|
||||
}
|
||||
return "[" + msg.toString() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDataInfo<SysLogininfor> selectPageLogininforList(SysLogininfor logininfor) {
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
package com.ruoyi.system.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.core.service.OperLogService;
|
||||
import com.ruoyi.common.core.domain.dto.OperLogDTO;
|
||||
import com.ruoyi.common.utils.PageUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.ip.AddressUtils;
|
||||
import com.ruoyi.system.domain.SysOperLog;
|
||||
import com.ruoyi.system.mapper.SysOperLogMapper;
|
||||
import com.ruoyi.system.service.ISysOperLogService;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -22,7 +27,21 @@ import java.util.Map;
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Service
|
||||
public class SysOperLogServiceImpl extends ServicePlusImpl<SysOperLogMapper, SysOperLog, SysOperLog> implements ISysOperLogService {
|
||||
public class SysOperLogServiceImpl extends ServicePlusImpl<SysOperLogMapper, SysOperLog, SysOperLog> implements ISysOperLogService, OperLogService {
|
||||
|
||||
/**
|
||||
* 操作日志记录
|
||||
*
|
||||
* @param operLogDTO 操作日志信息
|
||||
*/
|
||||
@Async
|
||||
@Override
|
||||
public void recordOper(final OperLogDTO operLogDTO) {
|
||||
SysOperLog operLog = BeanUtil.toBean(operLogDTO, SysOperLog.class);
|
||||
// 远程查询操作地点
|
||||
operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
|
||||
insertOperlog(operLog);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDataInfo<SysOperLog> selectPageOperLogList(SysOperLog operLog) {
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
package com.ruoyi.system.service.impl;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.http.useragent.UserAgent;
|
||||
import cn.hutool.http.useragent.UserAgentUtil;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.core.service.TokenService;
|
||||
import com.ruoyi.common.properties.TokenProperties;
|
||||
import com.ruoyi.common.utils.RedisUtils;
|
||||
import com.ruoyi.common.utils.ServletUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.ip.AddressUtils;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* token验证处理
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Component
|
||||
public class TokenServiceImpl implements TokenService {
|
||||
|
||||
protected static final long MILLIS_SECOND = 1000;
|
||||
|
||||
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
|
||||
|
||||
private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;
|
||||
|
||||
@Autowired
|
||||
private TokenProperties tokenProperties;
|
||||
|
||||
/**
|
||||
* 获取用户身份信息
|
||||
*
|
||||
* @return 用户信息
|
||||
*/
|
||||
public LoginUser getLoginUser(HttpServletRequest request) {
|
||||
// 获取请求携带的令牌
|
||||
String token = getToken(request);
|
||||
if (StringUtils.isNotEmpty(token)) {
|
||||
try {
|
||||
Claims claims = parseToken(token);
|
||||
// 解析对应的权限以及用户信息
|
||||
String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
|
||||
String userKey = getTokenKey(uuid);
|
||||
LoginUser user = RedisUtils.getCacheObject(userKey);
|
||||
return user;
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置用户身份信息
|
||||
*/
|
||||
public void setLoginUser(LoginUser loginUser) {
|
||||
if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) {
|
||||
refreshToken(loginUser);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户身份信息
|
||||
*/
|
||||
public void delLoginUser(String token) {
|
||||
if (StringUtils.isNotEmpty(token)) {
|
||||
String userKey = getTokenKey(token);
|
||||
RedisUtils.deleteObject(userKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建令牌
|
||||
*
|
||||
* @param loginUser 用户信息
|
||||
* @return 令牌
|
||||
*/
|
||||
public String createToken(LoginUser loginUser) {
|
||||
String token = IdUtil.fastUUID();
|
||||
loginUser.setToken(token);
|
||||
setUserAgent(loginUser);
|
||||
refreshToken(loginUser);
|
||||
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
claims.put(Constants.LOGIN_USER_KEY, token);
|
||||
return createToken(claims);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证令牌有效期,相差不足20分钟,自动刷新缓存
|
||||
*
|
||||
* @param loginUser
|
||||
* @return 令牌
|
||||
*/
|
||||
public void verifyToken(LoginUser loginUser) {
|
||||
long expireTime = loginUser.getExpireTime();
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
|
||||
refreshToken(loginUser);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新令牌有效期
|
||||
*
|
||||
* @param loginUser 登录信息
|
||||
*/
|
||||
public void refreshToken(LoginUser loginUser) {
|
||||
loginUser.setLoginTime(System.currentTimeMillis());
|
||||
loginUser.setExpireTime(loginUser.getLoginTime() + tokenProperties.getExpireTime() * MILLIS_MINUTE);
|
||||
// 根据uuid将loginUser缓存
|
||||
String userKey = getTokenKey(loginUser.getToken());
|
||||
RedisUtils.setCacheObject(userKey, loginUser, tokenProperties.getExpireTime(), TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置用户代理信息
|
||||
*
|
||||
* @param loginUser 登录信息
|
||||
*/
|
||||
public void setUserAgent(LoginUser loginUser) {
|
||||
UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
|
||||
String ip = ServletUtils.getClientIP();
|
||||
loginUser.setIpaddr(ip);
|
||||
loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
|
||||
loginUser.setBrowser(userAgent.getBrowser().getName());
|
||||
loginUser.setOs(userAgent.getOs().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据声明生成令牌
|
||||
*
|
||||
* @param claims 数据声明
|
||||
* @return 令牌
|
||||
*/
|
||||
private String createToken(Map<String, Object> claims) {
|
||||
String token = Jwts.builder()
|
||||
.setClaims(claims)
|
||||
.signWith(SignatureAlgorithm.HS512, tokenProperties.getSecret()).compact();
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从令牌中获取数据声明
|
||||
*
|
||||
* @param token 令牌
|
||||
* @return 数据声明
|
||||
*/
|
||||
private Claims parseToken(String token) {
|
||||
return Jwts.parser()
|
||||
.setSigningKey(tokenProperties.getSecret())
|
||||
.parseClaimsJws(token)
|
||||
.getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从令牌中获取用户名
|
||||
*
|
||||
* @param token 令牌
|
||||
* @return 用户名
|
||||
*/
|
||||
public String getUsernameFromToken(String token) {
|
||||
Claims claims = parseToken(token);
|
||||
return claims.getSubject();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求token
|
||||
*
|
||||
* @param request
|
||||
* @return token
|
||||
*/
|
||||
private String getToken(HttpServletRequest request) {
|
||||
String token = request.getHeader(tokenProperties.getHeader());
|
||||
if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) {
|
||||
token = token.replace(Constants.TOKEN_PREFIX, "");
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
private String getTokenKey(String uuid) {
|
||||
return Constants.LOGIN_TOKEN_KEY + uuid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.ruoyi.system.service.impl;
|
||||
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.enums.UserStatus;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.system.service.ISysUserService;
|
||||
import com.ruoyi.system.service.SysPermissionService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 用户验证处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class UserDetailsServiceImpl implements UserDetailsService
|
||||
{
|
||||
|
||||
@Autowired
|
||||
private ISysUserService userService;
|
||||
|
||||
@Autowired
|
||||
private SysPermissionService permissionService;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
|
||||
{
|
||||
SysUser user = userService.selectUserByUserName(username);
|
||||
if (StringUtils.isNull(user))
|
||||
{
|
||||
log.info("登录用户:{} 不存在.", username);
|
||||
throw new ServiceException("登录用户:" + username + " 不存在");
|
||||
}
|
||||
else if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
|
||||
{
|
||||
log.info("登录用户:{} 已被删除.", username);
|
||||
throw new ServiceException("对不起,您的账号:" + username + " 已被删除");
|
||||
}
|
||||
else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
|
||||
{
|
||||
log.info("登录用户:{} 已被停用.", username);
|
||||
throw new ServiceException("对不起,您的账号:" + username + " 已停用");
|
||||
}
|
||||
|
||||
return createLoginUser(user);
|
||||
}
|
||||
|
||||
public UserDetails createLoginUser(SysUser user)
|
||||
{
|
||||
return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user