From e1199724d209c29a7b640bc96d2ffa32acf381dc Mon Sep 17 00:00:00 2001 From: xuhy <3313886187@qq.com> Date: 星期二, 20 八月 2024 09:10:46 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java | 142 +++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 118 insertions(+), 24 deletions(-) diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java index 1b0eb25..c6653e5 100644 --- a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java @@ -1,18 +1,18 @@ package com.ruoyi.gateway.filter; -import com.alibaba.fastjson.JSONObject; -import org.apache.commons.codec.binary.Base64; +import com.ruoyi.account.api.feignClient.AppUserClient; +import com.ruoyi.account.api.model.TAppUser; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.api.feignClient.SysUserClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.context.annotation.Lazy; import org.springframework.core.Ordered; -import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.HttpHeaders; import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.http.server.reactive.ServerHttpRequestDecorator; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import com.ruoyi.common.core.constant.CacheConstants; @@ -25,14 +25,12 @@ import com.ruoyi.common.redis.service.RedisService; import com.ruoyi.gateway.config.properties.IgnoreWhiteProperties; import io.jsonwebtoken.Claims; -import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.concurrent.atomic.AtomicReference; +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; + /** * 网关鉴权 @@ -50,6 +48,15 @@ @Autowired private RedisService redisService; + @Lazy + @Resource + private AppUserClient appUserClient; + + @Lazy + @Resource + private SysUserClient sysUserClient; + + @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { @@ -61,24 +68,26 @@ if (StringUtils.matches(url, ignoreWhite.getWhites())) { return chain.filter(exchange); } + //防抖校验 + try { + antiShake(request); + }catch (Exception e){ + log.error("[重复提交]请求路径:{}", exchange.getRequest().getPath()); + return ServletUtils.webFluxResponseWriter(exchange.getResponse(), e.getMessage(), HttpStatus.SUCCESS); + } + + //校验账户是否有效 + try { + verifyToken(request); + verifyAccount(request); + }catch (Exception e){ + return unauthorizedResponse(exchange, e.getMessage()); + } String token = getToken(request); - if (StringUtils.isEmpty(token)) { - return unauthorizedResponse(exchange, "令牌不能为空"); - } Claims claims = JwtUtils.parseToken(token); - if (claims == null) { - return unauthorizedResponse(exchange, "令牌已过期或验证不正确!"); - } String userkey = JwtUtils.getUserKey(claims); - boolean islogin = redisService.hasKey(getTokenKey(userkey)); - if (!islogin) { - return unauthorizedResponse(exchange, "登录状态已过期"); - } String userid = JwtUtils.getUserId(claims); String username = JwtUtils.getUserName(claims); - if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username)) { - return unauthorizedResponse(exchange, "令牌验证失败"); - } // 设置用户信息到请求 addHeader(mutate, SecurityConstants.USER_KEY, userkey); @@ -130,9 +139,94 @@ /** * 防抖处理 */ + public void antiShake(ServerHttpRequest request) throws Exception{ + HttpHeaders headers = request.getHeaders(); + String client = headers.getFirst("client"); + String timestamp = headers.getFirst("timestamp"); + String url = request.getURI().getPath(); + Map<String, Object> cacheMap = redisService.getCacheMap(client); + if(null == cacheMap){ + cacheMap = new HashMap<>(); + cacheMap.put(url, timestamp); + redisService.setCacheMap(client, cacheMap); + }else{ + Object o = cacheMap.get(url); + if(null == o){ + cacheMap.put(url, timestamp); + }else{ + Long old_timestamp = Long.valueOf(o.toString()); + Long new_timestamp = Long.valueOf(timestamp); + //两个请求时间差小于1秒,判定为重复提交 + if((new_timestamp - old_timestamp) <= 1000){ + throw new RuntimeException("重复提交"); + }else{ + cacheMap.put(url, timestamp); + } + } + redisService.setCacheMap(client, cacheMap); + } + } + /** + * 验证token + * @param request + * @throws Exception + */ + public void verifyToken(ServerHttpRequest request) throws Exception{ + String token = getToken(request); + if (StringUtils.isEmpty(token)) { + throw new RuntimeException("令牌不能为空"); + } + Claims claims = JwtUtils.parseToken(token); + if (claims == null) { + throw new RuntimeException("令牌已过期或验证不正确!"); + } + String userkey = JwtUtils.getUserKey(claims); + boolean islogin = redisService.hasKey(getTokenKey(userkey)); + if (!islogin) { + throw new RuntimeException("登录状态已过期"); + } + String userid = JwtUtils.getUserId(claims); + String username = JwtUtils.getUserName(claims); + if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username)) { + throw new RuntimeException("令牌验证失败"); + } + } + + /** + * 校验账户是否有效 + * @param request + * @throws Exception + */ + public void verifyAccount(ServerHttpRequest request) throws Exception{ + String token = getToken(request); + Claims claims = JwtUtils.parseToken(token); + String userid = JwtUtils.getUserId(claims); + String userType = JwtUtils.getUserType(claims); + //管理后台用户 + if ("system".equals(userType)) { + SysUser sysUser = sysUserClient.getSysUser(Long.valueOf(userid)).getData(); + if(null == sysUser || "2".equals(sysUser.getDelFlag())){ + throw new RuntimeException("无效的账户"); + } + if("1".equals(sysUser.getStatus())){ + throw new RuntimeException("账户已被停用,请联系系统管理员!"); + } + } + //小程序用户 + if ("applet".equals(userType)) { + TAppUser appUser = appUserClient.getUserById(Long.valueOf(userid)).getData(); + if(null == appUser || appUser.getDelFlag() || 3 == appUser.getStatus()){ + throw new RuntimeException("无效的账户"); + } + if(2 == appUser.getStatus()){ + throw new RuntimeException("账户已被冻结,请联系系统管理员!"); + } + } + } + @Override public int getOrder() { -- Gitblit v1.7.1