RuoYi-Cloud-Plus 关于webFlux在Gateway生成验证码
生成验证码过程src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java#createCaptcha()验证码校验方法src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java#checkCaptcha()登录创建验证码 r
登录创建验证码 ruoyi-ui/src/views/login.vue
created() {
this.getCode();
this.getCookie();
},
methods: {
getCode() {
getCodeImg().then(res => {
this.captchaEnabled = res.data.captchaEnabled === undefined ? true : res.data.captchaEnabled;
if (this.captchaEnabled) {
this.codeUrl = "data:image/gif;base64," + res.data.img;
this.loginForm.uuid = res.data.uuid;
}
});
},
ruoyi-ui/src/api/login.js
// 获取验证码
export function getCodeImg() {
return request({
url: '/code',
headers: {
isToken: false
},
method: 'get',
timeout: 20000
})
}
com/ruoyi/gateway/config/RouterFunctionConfiguration.java
/**
* 路由配置信息
*
* @author ruoyi
*/
@Configuration
public class RouterFunctionConfiguration {
@Autowired
private ValidateCodeHandler validateCodeHandler;
@SuppressWarnings("rawtypes")
@Bean
public RouterFunction routerFunction() {
//匹配路径地址,请求类型,对应处理类
return RouterFunctions.route(
RequestPredicates.GET("/code").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
validateCodeHandler);
}
}
获取验证码src/main/java/com/ruoyi/gateway/handler/ValidateCodeHandler.java
/**
* 验证码获取
*
* @author ruoyi
*/
@Component
public class ValidateCodeHandler implements HandlerFunction<ServerResponse> {
@Autowired
private ValidateCodeService validateCodeService;
@Override
public Mono<ServerResponse> handle(ServerRequest serverRequest) {
R<Map<String, Object>> ajax;
try {
//创建验证码
ajax = validateCodeService.createCaptcha();
} catch (CaptchaException | IOException e) {
return Mono.error(e);
}
return ServerResponse.status(HttpStatus.OK).body(BodyInserters.fromValue(ajax));
}
}
验证码处理src/main/java/com/ruoyi/gateway/service/ValidateCodeService.java
/**
* 验证码处理
*
* @author ruoyi
*/
public interface ValidateCodeService {
/**
* 生成验证码
*/
R<Map<String, Object>> createCaptcha() throws IOException, CaptchaException;
/**
* 校验验证码
*/
void checkCaptcha(String key, String value) throws CaptchaException;
}
生成验证码过程src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java#createCaptcha()
/**
* 生成验证码
*/
@Override
public R<Map<String, Object>> createCaptcha() throws IOException, CaptchaException {
Map<String, Object> ajax = new HashMap<>();
boolean captchaEnabled = captchaProperties.getEnabled();
ajax.put("captchaEnabled", captchaEnabled);
if (!captchaEnabled) {
return R.ok(ajax);
}
// 保存验证码信息
String uuid = IdUtil.simpleUUID();
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
// 生成验证码
CaptchaType captchaType = captchaProperties.getType();
boolean isMath = CaptchaType.MATH == captchaType;
Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength();
CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length);
AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz());
captcha.setGenerator(codeGenerator);
captcha.createCode();
String code = captcha.getCode();
if (isMath) {
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(StringUtils.remove(code, "="));
code = exp.getValue(String.class);
}
RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
ajax.put("uuid", uuid);
ajax.put("img", captcha.getImageBase64());
return R.ok(ajax);
}
验证码验证src/main/java/com/ruoyi/gateway/filter/ValidateCodeFilter.java
/**
* 验证码过滤器
*
* @author ruoyi
*/
@Component
public class ValidateCodeFilter extends AbstractGatewayFilterFactory<Object> {
private final static String[] VALIDATE_URL = new String[]{"/auth/login", "/auth/register", "/auth/smsLogin"};
@Autowired
private ValidateCodeService validateCodeService;
@Autowired
private CaptchaProperties captchaProperties;
private static final String CODE = "code";
private static final String UUID = "uuid";
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
// 非登录/注册请求或验证码关闭,不处理
if (!StringUtils.equalsAnyIgnoreCase(request.getURI().getPath(), VALIDATE_URL) || !captchaProperties.getEnabled()) {
return chain.filter(exchange);
}
try {
String rspStr = WebFluxUtils.resolveBodyFromCacheRequest(exchange);
Dict obj = JsonUtils.parseMap(rspStr);
validateCodeService.checkCaptcha(obj.getStr(CODE), obj.getStr(UUID));
} catch (Exception e) {
return WebFluxUtils.webFluxResponseWriter(exchange.getResponse(), e.getMessage());
}
return chain.filter(exchange);
};
}
}
验证码校验方法src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java#checkCaptcha()
/**
* 校验验证码
*/
@Override
public void checkCaptcha(String code, String uuid) throws CaptchaException {
if (StringUtils.isEmpty(code)) {
throw new CaptchaException("user.jcaptcha.not.blank");
}
if (StringUtils.isEmpty(uuid)) {
throw new CaptchaExpireException();
}
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
String captcha = RedisUtils.getCacheObject(verifyKey);
RedisUtils.deleteObject(verifyKey);
if (!code.equalsIgnoreCase(captcha)) {
throw new CaptchaException();
}
}
更多推荐
所有评论(0)