| package com.ruoyi.gateway.filter; | 
|   | 
| import java.nio.CharBuffer; | 
| import java.nio.charset.StandardCharsets; | 
| import java.util.concurrent.atomic.AtomicReference; | 
|   | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.cloud.gateway.filter.GatewayFilter; | 
| import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; | 
| import org.springframework.core.io.buffer.DataBuffer; | 
| import org.springframework.core.io.buffer.DataBufferUtils; | 
| import org.springframework.http.server.reactive.ServerHttpRequest; | 
| import org.springframework.stereotype.Component; | 
| import com.alibaba.fastjson2.JSON; | 
| import com.alibaba.fastjson2.JSONObject; | 
| import com.ruoyi.common.core.utils.ServletUtils; | 
| import com.ruoyi.common.core.utils.StringUtils; | 
| import com.ruoyi.gateway.config.properties.CaptchaProperties; | 
| import com.ruoyi.gateway.service.ValidateCodeService; | 
| import reactor.core.publisher.Flux; | 
|   | 
| /** | 
|  * 验证码过滤器 | 
|  * | 
|  * @author ruoyi | 
|  */ | 
| @Component | 
| public class ValidateCodeFilter extends AbstractGatewayFilterFactory<Object> { | 
|     private final static String[] VALIDATE_URL = new String[]{"/auth/login", "/auth/register"}; | 
|     private static final String CODE = "code"; | 
|     private static final String UUID = "uuid"; | 
|     @Autowired | 
|     private ValidateCodeService validateCodeService; | 
|     @Autowired | 
|     private CaptchaProperties captchaProperties; | 
|      | 
|     @Override | 
|     public GatewayFilter apply(Object config) { | 
|         return (exchange, chain) -> { | 
|             ServerHttpRequest request = exchange.getRequest(); | 
|              | 
|             // 非登录/注册请求或验证码关闭,不处理 | 
|             if (!StringUtils.containsAnyIgnoreCase(request.getURI().getPath(), VALIDATE_URL) || !captchaProperties.getEnabled()) { | 
|                 return chain.filter(exchange); | 
|             } | 
|              | 
|             try { | 
|                 String rspStr = resolveBodyFromRequest(request); | 
|                 JSONObject obj = JSON.parseObject(rspStr); | 
|                 validateCodeService.checkCaptcha(obj.getString(CODE), obj.getString(UUID)); | 
|             } catch (Exception e) { | 
|                 return ServletUtils.webFluxResponseWriter(exchange.getResponse(), e.getMessage()); | 
|             } | 
|             return chain.filter(exchange); | 
|         }; | 
|     } | 
|      | 
|     private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) { | 
|         // 获取请求体 | 
|         Flux<DataBuffer> body = serverHttpRequest.getBody(); | 
|         AtomicReference<String> bodyRef = new AtomicReference<>(); | 
|         body.subscribe(buffer -> { | 
|             CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer()); | 
|             DataBufferUtils.release(buffer); | 
|             bodyRef.set(charBuffer.toString()); | 
|         }); | 
|         return bodyRef.get(); | 
|     } | 
| } |