feat: 获取用户信息ehcache缓存机制

This commit is contained in:
fit2cloud-chenyw 2021-03-19 13:05:14 +08:00
parent 670a640606
commit f0b34763d4
12 changed files with 119 additions and 23 deletions

View File

@ -1,10 +1,13 @@
package io.dataease.auth.config; package io.dataease.auth.config;
import io.dataease.auth.api.dto.CurrentRoleDto;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.auth.entity.JWTToken; import io.dataease.auth.entity.JWTToken;
import io.dataease.auth.entity.SysUserEntity; import io.dataease.auth.entity.SysUserEntity;
import io.dataease.auth.entity.TokenInfo; import io.dataease.auth.entity.TokenInfo;
import io.dataease.auth.service.AuthUserService; import io.dataease.auth.service.AuthUserService;
import io.dataease.auth.util.JWTUtils; import io.dataease.auth.util.JWTUtils;
import io.dataease.commons.utils.BeanUtils;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.AuthenticationToken;
@ -16,6 +19,8 @@ import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -58,7 +63,7 @@ public class F2CRealm extends AuthorizingRealm {
if (username == null) { if (username == null) {
throw new AuthenticationException("token invalid"); throw new AuthenticationException("token invalid");
} }
// 使用缓存
SysUserEntity user = authUserService.getUserById(userId); SysUserEntity user = authUserService.getUserById(userId);
if (user == null) { if (user == null) {
throw new AuthenticationException("User didn't existed!"); throw new AuthenticationException("User didn't existed!");
@ -72,6 +77,13 @@ public class F2CRealm extends AuthorizingRealm {
if (! JWTUtils.verify(token, tokenInfo, pass)) { if (! JWTUtils.verify(token, tokenInfo, pass)) {
throw new AuthenticationException("Username or password error"); throw new AuthenticationException("Username or password error");
} }
return new SimpleAuthenticationInfo(token, token, "f2cReam"); // 使用缓存
List<CurrentRoleDto> currentRoleDtos = authUserService.roleInfos(user.getUserId());
// 使用缓存
List<String> permissions = authUserService.permissions(user.getUserId());
CurrentUserDto currentUserDto = BeanUtils.copyBean(new CurrentUserDto(), user);
currentUserDto.setRoles(currentRoleDtos);
currentUserDto.setPermissions(permissions);
return new SimpleAuthenticationInfo(currentUserDto, token, "f2cReam");
} }
} }

View File

@ -15,6 +15,7 @@ import io.dataease.commons.utils.CodingUtil;
import io.dataease.commons.utils.ServletUtils; import io.dataease.commons.utils.ServletUtils;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -58,19 +59,26 @@ public class AuthServer implements AuthApi {
@Override @Override
public CurrentUserDto userInfo() { public CurrentUserDto userInfo() {
String token = ServletUtils.getToken(); CurrentUserDto userDto = (CurrentUserDto)SecurityUtils.getSubject().getPrincipal();
Long userId = JWTUtils.tokenInfoByToken(token).getUserId(); if (ObjectUtils.isEmpty(userDto)) {
SysUserEntity user = authUserService.getUserById(userId); String token = ServletUtils.getToken();
CurrentUserDto currentUserDto = BeanUtils.copyBean(new CurrentUserDto(), user); Long userId = JWTUtils.tokenInfoByToken(token).getUserId();
List<CurrentRoleDto> currentRoleDtos = authUserService.roleInfos(user.getUserId()); SysUserEntity user = authUserService.getUserById(userId);
List<String> permissions = authUserService.permissions(user.getUserId()); CurrentUserDto currentUserDto = BeanUtils.copyBean(new CurrentUserDto(), user);
currentUserDto.setRoles(currentRoleDtos); List<CurrentRoleDto> currentRoleDtos = authUserService.roleInfos(user.getUserId());
currentUserDto.setPermissions(permissions); List<String> permissions = authUserService.permissions(user.getUserId());
return currentUserDto; currentUserDto.setRoles(currentRoleDtos);
currentUserDto.setPermissions(permissions);
return currentUserDto;
}
return userDto;
} }
@Override @Override
public String logout(){ public String logout(){
String token = ServletUtils.getToken();
Long userId = JWTUtils.tokenInfoByToken(token).getUserId();
authUserService.clearCache(userId);
return "success"; return "success";
} }

View File

@ -19,6 +19,8 @@ public interface AuthUserService {
List<CurrentRoleDto> roleInfos(Long userId); List<CurrentRoleDto> roleInfos(Long userId);
void clearCache(Long userId);
} }

View File

@ -4,8 +4,11 @@ import io.dataease.auth.api.dto.CurrentRoleDto;
import io.dataease.auth.entity.SysUserEntity; import io.dataease.auth.entity.SysUserEntity;
import io.dataease.base.mapper.ext.AuthMapper; import io.dataease.base.mapper.ext.AuthMapper;
import io.dataease.auth.service.AuthUserService; import io.dataease.auth.service.AuthUserService;
import io.dataease.commons.constants.AuthConstants;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -16,7 +19,6 @@ import java.util.stream.Collectors;
@Service @Service
public class AuthUserServiceImpl implements AuthUserService { public class AuthUserServiceImpl implements AuthUserService {
private final String USER_CACHE_NAME = "users_info";
@Resource @Resource
private AuthMapper authMapper; private AuthMapper authMapper;
@ -26,7 +28,7 @@ public class AuthUserServiceImpl implements AuthUserService {
* @param userId * @param userId
* @return * @return
*/ */
@Cacheable(value = USER_CACHE_NAME, key = "'user' + #userId" ) @Cacheable(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #userId" )
@Override @Override
public SysUserEntity getUserById(Long userId){ public SysUserEntity getUserById(Long userId){
return authMapper.findUser(userId); return authMapper.findUser(userId);
@ -41,14 +43,42 @@ public class AuthUserServiceImpl implements AuthUserService {
public List<String> roles(Long userId){ public List<String> roles(Long userId){
return authMapper.roleCodes(userId); return authMapper.roleCodes(userId);
} }
/**
* 此处需被F2CRealm登录认证调用 也就是说每次请求都会被调用 所以最好加上缓存
* @param userId
* @return
*/
@Cacheable(value = AuthConstants.USER_PERMISSION_CACHE_NAME, key = "'user' + #userId" )
@Override @Override
public List<String> permissions(Long userId){ public List<String> permissions(Long userId){
List<String> permissions = authMapper.permissions(userId); List<String> permissions = authMapper.permissions(userId);
return permissions.stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList()); return permissions.stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
} }
/**
* 此处需被F2CRealm登录认证调用 也就是说每次请求都会被调用 所以最好加上缓存
* @param userId
* @return
*/
@Cacheable(value = AuthConstants.USER_ROLE_CACHE_NAME, key = "'user' + #userId" )
@Override @Override
public List<CurrentRoleDto> roleInfos(Long userId) { public List<CurrentRoleDto> roleInfos(Long userId) {
return authMapper.roles(userId); return authMapper.roles(userId);
} }
/**
* 一波清除3个缓存
* @param userId
*/
@Caching(evict = {
@CacheEvict(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #userId"),
@CacheEvict(value = AuthConstants.USER_ROLE_CACHE_NAME, key = "'user' + #userId"),
@CacheEvict(value = AuthConstants.USER_PERMISSION_CACHE_NAME, key = "'user' + #userId")
})
@Override
public void clearCache(Long userId) {
}
} }

View File

@ -3,4 +3,9 @@ package io.dataease.commons.constants;
public class AuthConstants { public class AuthConstants {
public final static String TOKEN_KEY = "Authorization"; public final static String TOKEN_KEY = "Authorization";
public final static String USER_CACHE_NAME = "users_info";
public final static String USER_ROLE_CACHE_NAME = "users_roles_info";
public final static String USER_PERMISSION_CACHE_NAME = "users_permissions_info";
} }

View File

@ -1,9 +1,11 @@
package io.dataease.commons.utils; package io.dataease.commons.utils;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.auth.entity.TokenInfo; import io.dataease.auth.entity.TokenInfo;
import io.dataease.auth.util.JWTUtils; import io.dataease.auth.util.JWTUtils;
import io.dataease.base.domain.SysUser; import io.dataease.base.domain.SysUser;
import io.dataease.service.sys.SysUserService; import io.dataease.service.sys.SysUserService;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -17,12 +19,18 @@ public class AuthUtils {
AuthUtils.sysUserService = sysUserService; AuthUtils.sysUserService = sysUserService;
} }
public static SysUser getUser(){ /*public static SysUser getUser(){
SecurityUtils.getSubject().getPrincipal()
String token = ServletUtils.getToken(); String token = ServletUtils.getToken();
TokenInfo tokenInfo = JWTUtils.tokenInfoByToken(token); TokenInfo tokenInfo = JWTUtils.tokenInfoByToken(token);
SysUser sysUser = new SysUser(); SysUser sysUser = new SysUser();
sysUser.setUserId(tokenInfo.getUserId()); sysUser.setUserId(tokenInfo.getUserId());
SysUser user = sysUserService.findOne(sysUser); SysUser user = sysUserService.findOne(sysUser);
return user; return user;
}*/
public static CurrentUserDto getUser(){
CurrentUserDto userDto = (CurrentUserDto)SecurityUtils.getSubject().getPrincipal();
return userDto;
} }
} }

View File

@ -49,7 +49,7 @@ public class SysUserController {
sysUserService.update(request); sysUserService.update(request);
} }
@ApiOperation("更新用户") @ApiOperation("删除用户")
@PostMapping("/delete/{userId}") @PostMapping("/delete/{userId}")
public void delete(@PathVariable("userId") Long userId){ public void delete(@PathVariable("userId") Long userId){
sysUserService.delete(userId); sysUserService.delete(userId);

View File

@ -1,5 +1,6 @@
package io.dataease.notice.service; package io.dataease.notice.service;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.base.domain.MessageTask; import io.dataease.base.domain.MessageTask;
import io.dataease.base.domain.MessageTaskExample; import io.dataease.base.domain.MessageTaskExample;
import io.dataease.base.domain.SysUser; import io.dataease.base.domain.SysUser;
@ -101,7 +102,7 @@ public class NoticeService {
} }
public List<MessageDetail> searchMessageByType(String type) { public List<MessageDetail> searchMessageByType(String type) {
SysUser user = AuthUtils.getUser(); CurrentUserDto user = AuthUtils.getUser();
//String orgId = user.getLastOrganizationId(); //String orgId = user.getLastOrganizationId();
List<MessageDetail> messageDetails = new ArrayList<>(); List<MessageDetail> messageDetails = new ArrayList<>();

View File

@ -1,5 +1,7 @@
package io.dataease.service.panel; package io.dataease.service.panel;
import io.dataease.auth.api.dto.CurrentRoleDto;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.base.domain.PanelShare; import io.dataease.base.domain.PanelShare;
import io.dataease.base.domain.PanelShareExample; import io.dataease.base.domain.PanelShareExample;
import io.dataease.base.domain.SysUser; import io.dataease.base.domain.SysUser;
@ -80,10 +82,10 @@ public class ShareService {
public List<PanelShareDto> queryTree(BaseGridRequest request){ public List<PanelShareDto> queryTree(BaseGridRequest request){
SysUser user = AuthUtils.getUser(); CurrentUserDto user = AuthUtils.getUser();
Long userId = user.getUserId(); Long userId = user.getUserId();
Long deptId = user.getDeptId(); Long deptId = user.getDeptId();
List<Long> roleIds = new ArrayList<>(); List<Long> roleIds = user.getRoles().stream().map(CurrentRoleDto::getId).collect(Collectors.toList());
List<Long> targetIds = new ArrayList<>(); List<Long> targetIds = new ArrayList<>();
targetIds.add(userId); targetIds.add(userId);

View File

@ -8,6 +8,7 @@ import io.dataease.base.mapper.SysUserMapper;
import io.dataease.base.mapper.SysUsersRolesMapper; import io.dataease.base.mapper.SysUsersRolesMapper;
import io.dataease.base.mapper.ext.ExtSysUserMapper; import io.dataease.base.mapper.ext.ExtSysUserMapper;
import io.dataease.base.mapper.ext.query.GridExample; import io.dataease.base.mapper.ext.query.GridExample;
import io.dataease.commons.constants.AuthConstants;
import io.dataease.commons.utils.BeanUtils; import io.dataease.commons.utils.BeanUtils;
import io.dataease.commons.utils.CodingUtil; import io.dataease.commons.utils.CodingUtil;
import io.dataease.controller.sys.base.BaseGridRequest; import io.dataease.controller.sys.base.BaseGridRequest;
@ -30,7 +31,6 @@ import java.util.stream.Collectors;
@Service @Service
public class SysUserService { public class SysUserService {
private final static String USER_CACHE_NAME = "users_info";
private final static String DEFAULT_PWD = "DataEase123.."; private final static String DEFAULT_PWD = "DataEase123..";
@Resource @Resource
@ -72,6 +72,12 @@ public class SysUserService {
return insert; return insert;
} }
/**
* 修改用户密码清楚缓存
* @param request
* @return
*/
@CacheEvict(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #request.userId")
@Transactional @Transactional
public int update(SysUserCreateRequest request){ public int update(SysUserCreateRequest request){
SysUser user = BeanUtils.copyBean(new SysUser(), request); SysUser user = BeanUtils.copyBean(new SysUser(), request);
@ -95,7 +101,7 @@ public class SysUserService {
* @param request * @param request
* @return * @return
*/ */
@CacheEvict(value = USER_CACHE_NAME, key = "'user' + #request.userId") @CacheEvict(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #request.userId")
public int updatePwd(SysUserPwdRequest request) { public int updatePwd(SysUserPwdRequest request) {
if (!StringUtils.equals(request.getPassword(), request.getRepeatPassword())){ if (!StringUtils.equals(request.getPassword(), request.getRepeatPassword())){
throw new RuntimeException("两次密码不一致"); throw new RuntimeException("两次密码不一致");
@ -115,7 +121,7 @@ public class SysUserService {
return sysUserMapper.updateByPrimaryKeySelective(sysUser); return sysUserMapper.updateByPrimaryKeySelective(sysUser);
} }
@CacheEvict(value = USER_CACHE_NAME, key = "'user' + #request.userId") @CacheEvict(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #request.userId")
public int adminUpdatePwd(SysUserPwdRequest request){ public int adminUpdatePwd(SysUserPwdRequest request){
SysUser sysUser = new SysUser(); SysUser sysUser = new SysUser();
sysUser.setUserId(request.getUserId()); sysUser.setUserId(request.getUserId());
@ -150,7 +156,7 @@ public class SysUserService {
}); });
} }
@CacheEvict(value = USER_CACHE_NAME, key = "'user' + #userId") @CacheEvict(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #userId")
@Transactional @Transactional
public int delete(Long userId){ public int delete(Long userId){
deleteUserRoles(userId); deleteUserRoles(userId);

View File

@ -46,6 +46,28 @@
timeToLiveSeconds="3600" timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LRU" memoryStoreEvictionPolicy="LRU"
/> />
<cache
name="users_roles_info"
eternal="false"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LRU"
/>
<cache
name="users_permissions_info"
eternal="false"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LRU"
/>
<cache <cache
name="tokens_expire" name="tokens_expire"

View File

@ -14,7 +14,7 @@ const RefreshTokenKey = Config.RefreshTokenKey
const service = axios.create({ const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests // withCredentials: true, // send cookies when cross-domain requests
timeout: 10000 // request timeout timeout: 0 // request timeout
}) })
// request interceptor // request interceptor