| | |
| | | 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.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; |
| | | |
| | | /** |
| | |
| | | */ |
| | | @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(); |
| | | } |
| | | 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<DataBuffer> getBody() { |
| | | return Flux.just(exchange.getResponse().bufferFactory().wrap(body)); |
| | | } |
| | | }; |
| | | return chain.filter(exchange.mutate().request(decoratedRequest).build()); |
| | | }); |
| | | }; |
| | | } |
| | | } |