package com.ruoyi.gateway.filter; import java.nio.charset.StandardCharsets; 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.http.server.reactive.ServerHttpRequestDecorator; 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 { private static final 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); } return DataBufferUtils.join(request.getBody()).flatMap(dataBuffer -> { byte[] body = new byte[dataBuffer.readableByteCount()]; dataBuffer.read(body); DataBufferUtils.release(dataBuffer); try { JSONObject json = JSON.parseObject(new String(body, StandardCharsets.UTF_8)); validateCodeService.checkCaptcha(json.getString(CODE), json.getString(UUID)); } catch (Exception e) { return ServletUtils.webFluxResponseWriter(exchange.getResponse(), e.getMessage()); } ServerHttpRequest decoratedRequest = new ServerHttpRequestDecorator(request) { @Override public Flux getBody() { return Flux.just(exchange.getResponse().bufferFactory().wrap(body)); } }; return chain.filter(exchange.mutate().request(decoratedRequest).build()); }); }; } }