redis工具類 http://www.reibang.com/p/1b3f33a045bf
- 相關(guān)依賴
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.9.0</version>
</dependency>
<!-- spring data redis 依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.6.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
- yml配置jwt
jwt:
authoritiesKey: auth
# 密匙KEY
secret: KeXu6IgYf7xaPe4jpw
# HeaderKEY
tokenHeader: Token
# jwt過期時間 單位秒 1天后過期=86400 7天后過期=604800
expiration: 1800
# 放入redis過期時間 單位秒 1天后過期=86400 7天后過期=604800
redisExpiration: 1800
獲取yml里的jwt配置信息
import lombok.Getter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* JWT配置類
*/
@Getter
@Component
@ConfigurationProperties(prefix = "jwt")
public class JWTConfig {
public static String authoritiesKey;
/**
* 密鑰KEY
*/
public static String secret;
/**
* TokenKey
*/
public static String tokenHeader;
/**
* 過期時間
*/
public static Integer expiration;
/**
* redis過期時間
*/
public static Integer redisExpiration;
public void setAuthoritiesKey(String authoritiesKey) {
this.authoritiesKey = authoritiesKey;
}
public void setSecret(String secret) {
this.secret = secret;
}
public void setTokenHeader(String tokenHeader) {
this.tokenHeader = tokenHeader;
}
public void setExpiration(Integer expiration) {
this.expiration = expiration;
}
public void setRedisExpiration(Integer redisExpiration) {
this.redisExpiration = redisExpiration;
}
}
- JwtTokenUtil用于解析和生成token
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.mp.generator.config.jwt.JWTConfig;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Date;
import java.util.Objects;
public class JwtTokenUtil implements Serializable {
private static final long serialVersionUID = -5625635588908941275L;
public static String generateToken(String username, Long current) {
if (null == current) {
current = System.currentTimeMillis();
}
Algorithm algorithm = Algorithm.HMAC256(JWTConfig.secret);
return JWT.create()
.withClaim(JWTConfig.authoritiesKey, username)
.withClaim("current", current)
.withExpiresAt(new Date(current + JWTConfig.expiration * 1000))
.sign(algorithm);
}
public static String getUsername(String token) {
try {
DecodedJWT jwt = JWT.decode(token);
return jwt.getClaim(JWTConfig.authoritiesKey).asString();
} catch (JWTDecodeException e) {
return null;
}
}
public static String getToken() {
String token;
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
token = request.getHeader(JWTConfig.tokenHeader);
if (StringUtils.isBlank(token)) {
return "";
}
return token;
}
public static boolean isExpired(String token) {
DecodedJWT jwt = JWT.decode(token);
Date expiration = jwt.getExpiresAt();
return expiration.before(new Date());
}
public static boolean verify(String token) {
try {
//解密
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(JWTConfig.secret)).build();
verifier.verify(token);
return true;
} catch (Exception e) {
return false;
}
}
public static Long getCurrent(String token){
try {
DecodedJWT jwt = JWT.decode(token);
return jwt.getClaim("current").asLong();
}catch (Exception e){
return null;
}
}
}
- UserToken,TokenFilter過濾器中使用利朵,傳遞token信息
import org.apache.shiro.authc.AuthenticationToken;
import java.io.Serializable;
public class UserToken implements AuthenticationToken, Serializable {
private static final long serialVersionUID = 1841491628743017587L;
private final String token;
public UserToken(String token) {
this.token = token;
}
@Override
public Object getPrincipal() {
return token;
}
@Override
public Object getCredentials() {
return token;
}
}
- 實現(xiàn)過濾器TokenFilter劲蜻,判斷用戶是否登錄
import com.mp.generator.config.jwt.JWTConfig;
import com.mp.generator.constants.RedisConstant;
import com.mp.generator.utils.JwtTokenUtil;
import com.mp.generator.utils.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
public class TokenFilter extends BasicHttpAuthenticationFilter {
private final Logger log = LoggerFactory.getLogger(this.getClass());
/**
* 如果帶有 com.token,則對 com.token 進(jìn)行檢查幅恋,否則直接通過
*/
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
//判斷請求的請求頭是否帶上 "Token"
if (isLoginAttempt(request, response)) {
//如果存在,則進(jìn)入 executeLogin 方法執(zhí)行登入泵肄,檢查 com.token 是否正確
try {
return executeLogin(request, response);
} catch (Exception e) {
log.error("shiro驗證異常 {}", Arrays.asList(e.getStackTrace()));
responseError(response, "shiro fail");
return false;
}
}
//1.如果請求頭不存在 Token捆交,則可能是執(zhí)行登陸操作或者是游客狀態(tài)訪問,無需檢查 com.token腐巢,直接返回 true
//2.如果請求頭不存在 Token品追,并且返回false,說明走我們的過濾器時必須帶token
return true;
}
/**
* 判斷用戶是否想要登入冯丙。
* 檢測 header 里面是否包含 JWTConfig.tokenHeader 字段
*/
@Override
protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) {
HttpServletRequest req = (HttpServletRequest) request;
String token = req.getHeader(JWTConfig.tokenHeader);
return StringUtils.isNotBlank(token);
}
/**
* 執(zhí)行登陸操作
*/
@Override
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String token = httpServletRequest.getHeader(JWTConfig.tokenHeader);
UserToken userToken = new UserToken(token);
try {
Subject subject = this.getSubject(request, response);
subject.login(userToken);
return this.onLoginSuccess(userToken, subject, request, response);
} catch (AuthenticationException var5) {
return this.onLoginFailure(userToken, var5, request, response);
}
}
/**
* 對跨域提供支持
*/
@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
// 跨域時會首先發(fā)送一個option請求肉瓦,這里我們給option請求直接返回正常狀態(tài)
if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
httpServletResponse.setStatus(HttpStatus.OK.value());
return false;
}
return super.preHandle(request, response);
}
/**
* token錯誤
*
* @param request
* @param response
* @return
* @throws Exception
*/
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
try {
String token = ((HttpServletRequest) request).getHeader(JWTConfig.tokenHeader);
log.info("--------token過期:{}--------", token);
} catch (Exception e) {
log.info("--------token不存在--------");
}
this.sendChallenge(request, response);
this.responseError(response, "token已過期或不存在!");
return Boolean.FALSE;
}
@Override
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
log.info("--------onLoginSuccess--------");
String tokenPrincipal = (String) token.getPrincipal();
if (StringUtils.isNotBlank(tokenPrincipal)) {
if (JwtTokenUtil.verify(tokenPrincipal)) {
return true;
} else {
return refreshToken(request, response);
}
}
return true;
}
/**
* 將非法請求跳轉(zhuǎn)到 /unauthorized/**
*/
private void responseError(ServletResponse response, String message) {
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
response.reset();
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("application/json; charset=utf-8");
String jsonStr = "{\"result\":\"FAILURE\",\"code\":401,\"message\":\"" + message + "\"}";
try (PrintWriter out = response.getWriter()) {
out.append(jsonStr);
} catch (IOException e) {
log.error("sendChallenge error,can not resolve httpServletResponse");
}
}
public <T> T getBean(Class<T> clazz, HttpServletRequest request) {
WebApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
return applicationContext.getBean(clazz);
}
// 刷新token
private boolean refreshToken(ServletRequest request, ServletResponse response) {
HttpServletRequest req = (HttpServletRequest) request;
RedisUtil redisUtil = getBean(RedisUtil.class, req);
// 獲取傳遞過來的accessToken
String accessToken = req.getHeader(JWTConfig.tokenHeader);
// 獲取token里面的用戶名
String username = JwtTokenUtil.getUsername(accessToken);
// 判斷refreshToken是否過期了,過期了那么所含的username的鍵不存在
if (redisUtil.hasKey(RedisConstant.CACHE_PREFIX + RedisConstant.CACHE_USER_ENTER + username)) {
// 判斷refresh的時間節(jié)點和傳遞過來的accessToken的時間節(jié)點是否一致,不一致校驗失敗
Long current = (Long) redisUtil.getCacheObject(RedisConstant.CACHE_PREFIX + RedisConstant.CACHE_USER_ENTER + username);
if (Objects.equals(JwtTokenUtil.getCurrent(accessToken), current)) {
// 獲取當(dāng)前時間節(jié)點
long currentTimeMillis = System.currentTimeMillis();
// 生成刷新的token
String token = JwtTokenUtil.generateToken(username, currentTimeMillis);
// 刷新redis里面的refreshToken,過期時間是(JWTConfig.expiration + 30*60)min
redisUtil.setCacheObject(RedisConstant.CACHE_PREFIX + RedisConstant.CACHE_USER_ENTER + username, currentTimeMillis, JWTConfig.expiration + JWTConfig.redisExpiration, TimeUnit.SECONDS);
// 最后將刷新的AccessToken存放在Response的Header中的JWTConfig.tokenHeader字段返回
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setHeader(JWTConfig.tokenHeader, token);
httpServletResponse.setHeader("Access-Control-Expose-Headers", JWTConfig.tokenHeader);
return true;
}
}
return false;
}
}
- 新建ShiroConfig泞莉,添加自己的過濾規(guī)則
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
@Slf4j
public class ShiroConfig {
/**
* 先走 com.**.TokenFilter 洁墙,然后 com.**.TokenFilter 如果檢測到請求頭存在token,則用token 去 login戒财,走 Realm 去驗證
*/
@Bean
public ShiroFilterFactoryBean factory(SecurityManager securityManager) {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
// 添加自己的過濾器并且取名為token
Map<String, Filter> filterMap = new HashMap<>();
//設(shè)置我們自定義的Token過濾器
filterMap.put("token", new TokenFilter());
factoryBean.setFilters(filterMap);
factoryBean.setSecurityManager(securityManager);
// 設(shè)置無權(quán)限時跳轉(zhuǎn)的 url;
factoryBean.setUnauthorizedUrl("/unauthorized/無權(quán)限");
Map<String, String> filterRuleMap = new LinkedHashMap<>();
filterRuleMap.put("/unauthorized/**", "anon");
filterRuleMap.put("/api/login/**", "anon");
filterRuleMap.put("/**", "token");
factoryBean.setFilterChainDefinitionMap(filterRuleMap);
return factoryBean;
}
/**
* 注入 securityManager
*/
@Bean
public SecurityManager securityManager(UserRealm userRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 設(shè)置自定義 realm.
securityManager.setRealm(userRealm);
/*
* 關(guān)閉shiro自帶的session热监,詳情見文檔
* http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
*/
DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
securityManager.setSubjectDAO(subjectDAO);
return securityManager;
}
/**
* 添加注解支持
*/
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
}
- UserRealm,對登錄用戶和用戶的權(quán)限進(jìn)行驗證
import cn.hutool.core.util.ObjectUtil;
import com.mp.generator.entity.SysMenu;
import com.mp.generator.entity.SysRole;
import com.mp.generator.entity.UserInfo;
import com.mp.generator.service.UserInfoService;
import com.mp.generator.utils.JwtTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import java.util.stream.Collectors;
@Slf4j
@Component
public class UserRealm extends AuthorizingRealm {
@Lazy
@Autowired
private UserInfoService userInfoService;
/**
* 必須重寫此方法饮寞,不然會報錯
*/
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof UserToken;
}
/**
* 授權(quán)
* 只有當(dāng)需要檢測用戶權(quán)限的時候才會調(diào)用此方法孝扛,例如checkRole,checkPermission之類的
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
log.info("授權(quán)驗證->doGetAuthenticationInfo()");
String token = principals.toString();
String username = JwtTokenUtil.getUsername(token);
UserInfo userInfo = userInfoService.getUserByUsername(username);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//查詢數(shù)據(jù)庫來獲取用戶的角色
info.addRoles(userInfo.getRoleList().stream().map(SysRole::getRoleName).collect(Collectors.toSet()));
//查詢數(shù)據(jù)庫來獲取用戶的權(quán)限
info.addStringPermissions(userInfo.getMenuList().stream().map(SysMenu::getPermission).collect(Collectors.toSet()));
return info;
}
/**
* 身份驗證
* 默認(rèn)使用此方法進(jìn)行用戶名正確與否驗證,錯誤拋出異常即可幽崩。
*
* @param authenticationToken token
* @return SimpleAuthenticationInfo
* @throws AuthenticationException 登錄異常
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
log.info("登錄驗證->doGetAuthenticationInfo()");
String token = (String) authenticationToken.getCredentials();
log.info("當(dāng)前token : {}", token);
String username = JwtTokenUtil.getUsername(token);
if (ObjectUtil.isNull(username)) {
throw new AuthenticationException("登錄過期,請重新登錄!");
}
UserInfo userInfo = userInfoService.getUserByUsername(username);
if (null == userInfo) {
throw new AuthenticationException("該用戶不存在");
}
log.info("當(dāng)前用戶 : {}", userInfo);
return new SimpleAuthenticationInfo(token, token, "UserRealm");
}
}
- 登錄實現(xiàn)
import com.mp.generator.config.jwt.JWTConfig;
import com.mp.generator.constants.RedisConstant;
import com.mp.generator.dto.request.LoginRequest;
import com.mp.generator.entity.UserInfo;
import com.mp.generator.service.LoginService;
import com.mp.generator.service.UserInfoService;
import com.mp.generator.utils.JwtTokenUtil;
import com.mp.generator.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service
public class LoginServiceImpl implements LoginService {
@Autowired
private UserInfoService userInfoService;
@Autowired
private RedisUtil redisUtil;
@Override
public String login(LoginRequest request) {
if (StringUtils.isBlank(request.getPassword())) {
throw new RuntimeException("請輸入密碼");
}
UserInfo userInfo = userInfoService.getUserInfo(request.getUserName());
if (null == userInfo) {
throw new RuntimeException("用戶名不存在");
}
String password = new SimpleHash("MD5", request.getPassword(), userInfo.getSalt(), 1024).toHex();
if (!password.equals(userInfo.getPassword())) {
throw new RuntimeException("密碼不正確");
}
long currentTimeMillis = System.currentTimeMillis();
String token = JwtTokenUtil.generateToken(userInfo.getUserName(), currentTimeMillis);
redisUtil.setCacheObject(RedisConstant.CACHE_PREFIX + RedisConstant.CACHE_USER_ENTER + userInfo.getUserName(), currentTimeMillis, JWTConfig.expiration + JWTConfig.redisExpiration, TimeUnit.SECONDS);
redisUtil.deleteObject(RedisConstant.CACHE_PREFIX + RedisConstant.CACHE_USER_INFO + userInfo.getUserName());
userInfoService.getUserByUsername(userInfo.getUserName());
return token;
}
}
UserInfoServiceImpl
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mp.generator.config.jwt.JWTConfig;
import com.mp.generator.entity.SysMenu;
import com.mp.generator.entity.SysRole;
import com.mp.generator.entity.UserInfo;
import com.mp.generator.constants.RedisConstant;
import com.mp.generator.mapper.UserInfoMapper;
import com.mp.generator.service.UserInfoService;
import com.mp.generator.utils.JwtTokenUtil;
import com.mp.generator.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
@Autowired
private RedisUtil redisUtil;
@Override
public UserInfo getUserInfo(String username) {
return baseMapper.selectOne(Wrappers.<UserInfo>lambdaQuery().eq(UserInfo::getUserName, username).last("LIMIT 1"));
}
@Override
public UserInfo getUserByUsername(String username) {
UserInfo userInfo = (UserInfo) redisUtil.getCacheObject(RedisConstant.CACHE_PREFIX + RedisConstant.CACHE_USER_INFO + username);
if (null == userInfo) {
log.info("redis緩存用戶已過期");
userInfo = this.getUserInfo(username);
if (null == userInfo) {
throw new AuthenticationException("用戶不存在");
}
List<SysRole> roleList = this.selectSysRoleByUserId(userInfo.getId());
List<SysMenu> menuList = this.selectSysMenuByUserId(userInfo.getId());
menuList.add(new SysMenu().setName("添加用戶").setPermission("user:add"));
menuList.add(new SysMenu().setName("用戶分頁").setPermission("user:page"));
userInfo.setRoleList(roleList);
userInfo.setMenuList(menuList);
redisUtil.setCacheObject(RedisConstant.CACHE_PREFIX + RedisConstant.CACHE_USER_INFO + userInfo.getUserName(), userInfo, JWTConfig.expiration + JWTConfig.redisExpiration, TimeUnit.SECONDS);
}
return userInfo;
}
@Override
public UserInfo getCurrentUserInfo() {
return this.getCurrentUserInfo(Boolean.FALSE);
}
@Override
public UserInfo getCurrentUserInfo(Boolean forceRefresh) {
String username = JwtTokenUtil.getUsername(JwtTokenUtil.getToken());
if (Boolean.TRUE.equals(forceRefresh)) {
redisUtil.deleteObject(RedisConstant.CACHE_PREFIX + RedisConstant.CACHE_USER_INFO + username);
}
return this.getUserByUsername(username);
}
@Override
public List<SysRole> selectSysRoleByUserId(Long userId) {
// 具體根據(jù)業(yè)務(wù)實現(xiàn)
return new ArrayList<>();
}
@Override
public List<SysMenu> selectSysMenuByUserId(Long userId) {
// 具體根據(jù)業(yè)務(wù)實現(xiàn)
return new ArrayList<>();
}
}