mirror of
https://gitee.com/y_project/RuoYi-Cloud.git
synced 2026-01-26 11:51:55 +08:00
若依 1.0
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
package com.ruoyi.gateway;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
|
||||
/**
|
||||
* 网关启动程序
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
|
||||
public class RuoYiGatewayApplication
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
SpringApplication.run(RuoYiGatewayApplication.class, args);
|
||||
System.out.println("(♥◠‿◠)ノ゙ 若依网关启动成功 ლ(´ڡ`ლ)゙ \n" +
|
||||
" .-------. ____ __ \n" +
|
||||
" | _ _ \\ \\ \\ / / \n" +
|
||||
" | ( ' ) | \\ _. / ' \n" +
|
||||
" |(_ o _) / _( )_ .' \n" +
|
||||
" | (_,_).' __ ___(_ o _)' \n" +
|
||||
" | |\\ \\ | || |(_,_)' \n" +
|
||||
" | | \\ `' /| `-' / \n" +
|
||||
" | | \\ / \\ / \n" +
|
||||
" ''-' `'-' `-..-' ");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.ruoyi.gateway.config;
|
||||
|
||||
import java.util.Properties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import com.google.code.kaptcha.impl.DefaultKaptcha;
|
||||
import com.google.code.kaptcha.util.Config;
|
||||
|
||||
/**
|
||||
* 验证码配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
public class CaptchaConfig
|
||||
{
|
||||
@Bean(name = "captchaProducerMath")
|
||||
public DefaultKaptcha getKaptchaBeanMath()
|
||||
{
|
||||
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
|
||||
Properties properties = new Properties();
|
||||
// 是否有边框 默认为true 我们可以自己设置yes,no
|
||||
properties.setProperty("kaptcha.border", "yes");
|
||||
// 边框颜色 默认为Color.BLACK
|
||||
properties.setProperty("kaptcha.border.color", "105,179,90");
|
||||
// 验证码文本字符颜色 默认为Color.BLACK
|
||||
properties.setProperty("kaptcha.textproducer.font.color", "blue");
|
||||
// 验证码图片宽度 默认为200
|
||||
properties.setProperty("kaptcha.image.width", "160");
|
||||
// 验证码图片高度 默认为50
|
||||
properties.setProperty("kaptcha.image.height", "60");
|
||||
// 验证码文本字符大小 默认为40
|
||||
properties.setProperty("kaptcha.textproducer.font.size", "35");
|
||||
// KAPTCHA_SESSION_KEY
|
||||
properties.setProperty("kaptcha.session.key", "kaptchaCodeMath");
|
||||
// 验证码文本生成器
|
||||
properties.setProperty("kaptcha.textproducer.impl", "com.ruoyi.gateway.config.KaptchaTextCreator");
|
||||
// 验证码文本字符间距 默认为2
|
||||
properties.setProperty("kaptcha.textproducer.char.space", "3");
|
||||
// 验证码文本字符长度 默认为5
|
||||
properties.setProperty("kaptcha.textproducer.char.length", "6");
|
||||
// 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1,
|
||||
// fontSize)
|
||||
properties.setProperty("kaptcha.textproducer.font.names", "Arial,Courier");
|
||||
// 验证码噪点颜色 默认为Color.BLACK
|
||||
properties.setProperty("kaptcha.noise.color", "white");
|
||||
// 干扰实现类
|
||||
properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.NoNoise");
|
||||
// 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple
|
||||
// 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy
|
||||
// 阴影com.google.code.kaptcha.impl.ShadowGimpy
|
||||
properties.setProperty("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.ShadowGimpy");
|
||||
Config config = new Config(properties);
|
||||
defaultKaptcha.setConfig(config);
|
||||
return defaultKaptcha;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.ruoyi.gateway.config;
|
||||
|
||||
import java.util.Random;
|
||||
import com.google.code.kaptcha.text.impl.DefaultTextCreator;
|
||||
|
||||
/**
|
||||
* 验证码文本生成器
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class KaptchaTextCreator extends DefaultTextCreator
|
||||
{
|
||||
private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(",");
|
||||
|
||||
@Override
|
||||
public String getText()
|
||||
{
|
||||
Integer result = 0;
|
||||
Random random = new Random();
|
||||
int x = random.nextInt(10);
|
||||
int y = random.nextInt(10);
|
||||
StringBuilder suChinese = new StringBuilder();
|
||||
int randomoperands = (int) Math.round(Math.random() * 2);
|
||||
if (randomoperands == 0)
|
||||
{
|
||||
result = x * y;
|
||||
suChinese.append(CNUMBERS[x]);
|
||||
suChinese.append("*");
|
||||
suChinese.append(CNUMBERS[y]);
|
||||
}
|
||||
else if (randomoperands == 1)
|
||||
{
|
||||
if (!(x == 0) && y % x == 0)
|
||||
{
|
||||
result = y / x;
|
||||
suChinese.append(CNUMBERS[y]);
|
||||
suChinese.append("/");
|
||||
suChinese.append(CNUMBERS[x]);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = x + y;
|
||||
suChinese.append(CNUMBERS[x]);
|
||||
suChinese.append("+");
|
||||
suChinese.append(CNUMBERS[y]);
|
||||
}
|
||||
}
|
||||
else if (randomoperands == 2)
|
||||
{
|
||||
if (x >= y)
|
||||
{
|
||||
result = x - y;
|
||||
suChinese.append(CNUMBERS[x]);
|
||||
suChinese.append("-");
|
||||
suChinese.append(CNUMBERS[y]);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = y - x;
|
||||
suChinese.append(CNUMBERS[y]);
|
||||
suChinese.append("-");
|
||||
suChinese.append(CNUMBERS[x]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = x + y;
|
||||
suChinese.append(CNUMBERS[x]);
|
||||
suChinese.append("+");
|
||||
suChinese.append(CNUMBERS[y]);
|
||||
}
|
||||
suChinese.append("=?@" + result);
|
||||
return suChinese.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.ruoyi.gateway.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicates;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import com.ruoyi.gateway.handler.HystrixFallbackHandler;
|
||||
import com.ruoyi.gateway.handler.ImageCodeHandler;
|
||||
|
||||
/**
|
||||
* 路由配置信息
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
public class RouterFunctionConfiguration
|
||||
{
|
||||
@Autowired
|
||||
private HystrixFallbackHandler hystrixFallbackHandler;
|
||||
|
||||
@Autowired
|
||||
private ImageCodeHandler imageCodeHandler;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Bean
|
||||
public RouterFunction routerFunction()
|
||||
{
|
||||
return RouterFunctions
|
||||
.route(RequestPredicates.path("/fallback").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
|
||||
hystrixFallbackHandler)
|
||||
.andRoute(RequestPredicates.GET("/code").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
|
||||
imageCodeHandler);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.ruoyi.gateway.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.gateway.config.GatewayProperties;
|
||||
import org.springframework.cloud.gateway.route.RouteLocator;
|
||||
import org.springframework.cloud.gateway.support.NameUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import springfox.documentation.swagger.web.SwaggerResource;
|
||||
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
|
||||
|
||||
@Component
|
||||
public class SwaggerProvider implements SwaggerResourcesProvider
|
||||
{
|
||||
/**
|
||||
* Swagger2默认的url后缀
|
||||
*/
|
||||
public static final String SWAGGER2URL = "/v2/api-docs";
|
||||
/**
|
||||
* 网关路由
|
||||
*/
|
||||
@Autowired
|
||||
private RouteLocator routeLocator;
|
||||
|
||||
@Autowired
|
||||
private GatewayProperties gatewayProperties;
|
||||
|
||||
/**
|
||||
* 聚合其他服务接口
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<SwaggerResource> get()
|
||||
{
|
||||
List<SwaggerResource> resourceList = new ArrayList<>();
|
||||
List<String> routes = new ArrayList<>();
|
||||
// 获取网关中配置的route
|
||||
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
|
||||
gatewayProperties.getRoutes().stream()
|
||||
.filter(routeDefinition -> routes
|
||||
.contains(routeDefinition.getId()))
|
||||
.forEach(routeDefinition -> routeDefinition.getPredicates().stream()
|
||||
.filter(predicateDefinition -> "Path".equalsIgnoreCase(predicateDefinition.getName()))
|
||||
.filter(predicateDefinition -> !"ruoyi-auth".equalsIgnoreCase(routeDefinition.getId()))
|
||||
.forEach(predicateDefinition -> resourceList
|
||||
.add(swaggerResource(routeDefinition.getId(), predicateDefinition.getArgs()
|
||||
.get(NameUtils.GENERATED_NAME_PREFIX + "0").replace("/**", SWAGGER2URL)))));
|
||||
return resourceList;
|
||||
}
|
||||
|
||||
private SwaggerResource swaggerResource(String name, String location)
|
||||
{
|
||||
SwaggerResource swaggerResource = new SwaggerResource();
|
||||
swaggerResource.setName(name);
|
||||
swaggerResource.setLocation(location);
|
||||
swaggerResource.setSwaggerVersion("2.0");
|
||||
return swaggerResource;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.ruoyi.gateway.config.properties;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 放行终端配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
@RefreshScope
|
||||
@ConfigurationProperties(prefix = "ignore")
|
||||
public class IgnoreClientProperties
|
||||
{
|
||||
/**
|
||||
* 放行终端配置,网关不校验此处的终端
|
||||
*/
|
||||
private List<String> clients = new ArrayList<>();
|
||||
|
||||
public List<String> getClients()
|
||||
{
|
||||
return clients;
|
||||
}
|
||||
|
||||
public void setClients(List<String> clients)
|
||||
{
|
||||
this.clients = clients;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.ruoyi.gateway.filter;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
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.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.ruoyi.common.core.constant.Constants;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.exception.ValidateCodeException;
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
import com.ruoyi.common.core.utils.web.WebUtils;
|
||||
import com.ruoyi.common.redis.service.RedisService;
|
||||
import com.ruoyi.gateway.config.properties.IgnoreClientProperties;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 验证码处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Component
|
||||
public class ImageCodeFilter extends AbstractGatewayFilterFactory
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(ImageCodeFilter.class);
|
||||
|
||||
@Autowired
|
||||
private IgnoreClientProperties ignoreClient;
|
||||
|
||||
private final static String AUTH_URL = "/oauth/token";
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@Override
|
||||
public GatewayFilter apply(Object config)
|
||||
{
|
||||
return (exchange, chain) -> {
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
|
||||
// 不是登录请求,直接向下执行
|
||||
if (!StringUtils.containsIgnoreCase(request.getURI().getPath(), AUTH_URL))
|
||||
{
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
try
|
||||
{
|
||||
String[] clientInfos = WebUtils.getClientId(request);
|
||||
if (ignoreClient.getClients().contains(clientInfos[0]))
|
||||
{
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
checkCode(request.getQueryParams());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ServerHttpResponse response = exchange.getResponse();
|
||||
try
|
||||
{
|
||||
return exchange.getResponse().writeWith(Mono.just(response.bufferFactory()
|
||||
.wrap(objectMapper.writeValueAsBytes(
|
||||
R.failed(e.getMessage())))));
|
||||
}
|
||||
catch (JsonProcessingException e1)
|
||||
{
|
||||
log.error("对象输出异常", e1);
|
||||
}
|
||||
}
|
||||
return chain.filter(exchange);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验验证码
|
||||
*/
|
||||
private void checkCode(MultiValueMap<String, String> getQueryParams) throws ValidateCodeException
|
||||
{
|
||||
String code = getQueryParams.getFirst("code");
|
||||
String uuid = getQueryParams.getFirst("uuid");
|
||||
if (StringUtils.isEmpty(code))
|
||||
{
|
||||
throw new ValidateCodeException("验证码不能为空");
|
||||
}
|
||||
if (StringUtils.isEmpty(uuid))
|
||||
{
|
||||
throw new ValidateCodeException("验证码已失效");
|
||||
}
|
||||
String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
|
||||
String captcha = redisService.getCacheObject(verifyKey);
|
||||
redisService.deleteObject(verifyKey);
|
||||
|
||||
if (!code.equalsIgnoreCase(captcha))
|
||||
{
|
||||
throw new ValidateCodeException("验证码错误");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.ruoyi.gateway.filter;
|
||||
|
||||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
|
||||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.addOriginalRequestUrl;
|
||||
import java.util.Arrays;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 全局拦截器
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Component
|
||||
public class RequestGlobalFilter implements GlobalFilter, Ordered
|
||||
{
|
||||
private static final String[] whiteList = {"/auth/oauth/token"};
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
|
||||
{
|
||||
String url = exchange.getRequest().getURI().getPath();
|
||||
// 跳过不需要验证的路径
|
||||
if (Arrays.asList(whiteList).contains(url))
|
||||
{
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
// 清洗请求头中from 参数
|
||||
ServerHttpRequest request = exchange.getRequest().mutate()
|
||||
.headers(httpHeaders -> httpHeaders.remove("from"))
|
||||
.build();
|
||||
|
||||
addOriginalRequestUrl(exchange, request.getURI());
|
||||
String rawPath = request.getURI().getRawPath();
|
||||
ServerHttpRequest newRequest = request.mutate()
|
||||
.path(rawPath)
|
||||
.build();
|
||||
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newRequest.getURI());
|
||||
|
||||
return chain.filter(exchange.mutate()
|
||||
.request(newRequest.mutate()
|
||||
.build()).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder()
|
||||
{
|
||||
return -1000;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.ruoyi.gateway.handler;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.server.HandlerFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
import java.util.Optional;
|
||||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR;
|
||||
|
||||
/**
|
||||
* 熔断降级处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Component
|
||||
public class HystrixFallbackHandler implements HandlerFunction<ServerResponse>
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(HystrixFallbackHandler.class);
|
||||
|
||||
@Override
|
||||
public Mono<ServerResponse> handle(ServerRequest serverRequest)
|
||||
{
|
||||
Optional<Object> originalUris = serverRequest.attribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR);
|
||||
originalUris.ifPresent(originalUri -> log.error("网关执行请求:{}失败,hystrix服务降级处理", originalUri));
|
||||
return ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR.value()).contentType(MediaType.APPLICATION_JSON)
|
||||
.body(BodyInserters.fromValue(JSON.toJSONString(R.failed("服务已被降级熔断"))));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.ruoyi.gateway.handler;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.imageio.ImageIO;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.FastByteArrayOutputStream;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.server.HandlerFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import com.google.code.kaptcha.Producer;
|
||||
import com.ruoyi.common.core.constant.Constants;
|
||||
import com.ruoyi.common.core.utils.IdUtils;
|
||||
import com.ruoyi.common.core.utils.sign.Base64;
|
||||
import com.ruoyi.common.core.web.domain.AjaxResult;
|
||||
import com.ruoyi.common.redis.service.RedisService;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 验证码获取
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Component
|
||||
public class ImageCodeHandler implements HandlerFunction<ServerResponse>
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(ImageCodeHandler.class);
|
||||
|
||||
@Autowired
|
||||
private Producer producer;
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@Override
|
||||
public Mono<ServerResponse> handle(ServerRequest serverRequest)
|
||||
{
|
||||
// 生成验证码
|
||||
String capText = producer.createText();
|
||||
String capStr = capText.substring(0, capText.lastIndexOf("@"));
|
||||
String verifyCode = capText.substring(capText.lastIndexOf("@") + 1);
|
||||
BufferedImage image = producer.createImage(capStr);
|
||||
// 保存验证码信息
|
||||
String uuid = IdUtils.simpleUUID();
|
||||
String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
|
||||
|
||||
redisService.setCacheObject(verifyKey, verifyCode, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
|
||||
|
||||
// 转换流信息写出
|
||||
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
|
||||
try
|
||||
{
|
||||
ImageIO.write(image, "jpg", os);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("ImageIO write err", e);
|
||||
return Mono.error(e);
|
||||
}
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("uuid", uuid);
|
||||
ajax.put("img", Base64.encode(os.toByteArray()));
|
||||
return ServerResponse.status(HttpStatus.OK)
|
||||
.body(BodyInserters.fromValue(ajax));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.ruoyi.gateway.handler;
|
||||
|
||||
import java.util.Optional;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import reactor.core.publisher.Mono;
|
||||
import springfox.documentation.swagger.web.SecurityConfiguration;
|
||||
import springfox.documentation.swagger.web.SecurityConfigurationBuilder;
|
||||
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
|
||||
import springfox.documentation.swagger.web.UiConfiguration;
|
||||
import springfox.documentation.swagger.web.UiConfigurationBuilder;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/swagger-resources")
|
||||
public class SwaggerHandler
|
||||
{
|
||||
@Autowired(required = false)
|
||||
private SecurityConfiguration securityConfiguration;
|
||||
|
||||
@Autowired(required = false)
|
||||
private UiConfiguration uiConfiguration;
|
||||
|
||||
private final SwaggerResourcesProvider swaggerResources;
|
||||
|
||||
@Autowired
|
||||
public SwaggerHandler(SwaggerResourcesProvider swaggerResources)
|
||||
{
|
||||
this.swaggerResources = swaggerResources;
|
||||
}
|
||||
|
||||
@GetMapping("/configuration/security")
|
||||
public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration()
|
||||
{
|
||||
return Mono.just(new ResponseEntity<>(
|
||||
Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()),
|
||||
HttpStatus.OK));
|
||||
}
|
||||
|
||||
@GetMapping("/configuration/ui")
|
||||
public Mono<ResponseEntity<UiConfiguration>> uiConfiguration()
|
||||
{
|
||||
return Mono.just(new ResponseEntity<>(
|
||||
Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@GetMapping("")
|
||||
public Mono<ResponseEntity> swaggerResources()
|
||||
{
|
||||
return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
|
||||
}
|
||||
}
|
||||
10
ruoyi-gateway/src/main/resources/banner.txt
Normal file
10
ruoyi-gateway/src/main/resources/banner.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Spring Boot Version: ${spring-boot.version}
|
||||
Spring Application Name: ${spring.application.name}
|
||||
_ _
|
||||
(_) | |
|
||||
_ __ _ _ ___ _ _ _ ______ __ _ __ _ | |_ ___ __ __ __ _ _ _
|
||||
| '__|| | | | / _ \ | | | || ||______| / _` | / _` || __| / _ \\ \ /\ / / / _` || | | |
|
||||
| | | |_| || (_) || |_| || | | (_| || (_| || |_ | __/ \ V V / | (_| || |_| |
|
||||
|_| \__,_| \___/ \__, ||_| \__, | \__,_| \__| \___| \_/\_/ \__,_| \__, |
|
||||
__/ | __/ | __/ |
|
||||
|___/ |___/ |___/
|
||||
24
ruoyi-gateway/src/main/resources/bootstrap.yml
Normal file
24
ruoyi-gateway/src/main/resources/bootstrap.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
# Tomcat
|
||||
server:
|
||||
port: 8080
|
||||
|
||||
# Spring
|
||||
spring:
|
||||
application:
|
||||
# 应用名称
|
||||
name: ruoyi-gateway
|
||||
profiles:
|
||||
# 环境配置
|
||||
active: dev
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
# 服务注册地址
|
||||
server-addr: 127.0.0.1:8848
|
||||
config:
|
||||
# 配置中心地址
|
||||
server-addr: 127.0.0.1:8848
|
||||
# 配置文件格式
|
||||
file-extension: yml
|
||||
# 共享配置
|
||||
shared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||
Reference in New Issue
Block a user