Pig4Cloud之验证码

2022-12-07 14:09:44 浏览数 (1)

## 登陆前端代码

```

<template #append>

<div class="login-code">

<span

class="login-code-img"

@click="refreshCode"

v-if="code.type === 'text'"

>{{ code.value }}</span

>

<img

:src="code.src"

class="login-code-img"

@click="refreshCode"

v-else

/>

</div>

</template>

```

刷新验证码代码

```

refreshCode() {

this.loginForm.code = "";

this.loginForm.randomStr = randomLenNum(this.code.len, true);

this.code.type === "text"

? (this.code.value = randomLenNum(this.code.len))

: (this.code.src = `${this.baseUrl}/code?randomStr=${this.loginForm.randomStr}`);

}

```

## 验证码配置开关

### 前端开关

位于website.js中配置validateCode属性

```

validateCode: true,//是否开启验证码校验

```

### 后端开关

位于pig-gateway-dev.yml配置文件

```

# 不校验验证码终端

gateway:

encode-key: 'thanks,pig4cloud'

ignore-clients:

- test

- client

```

## 生成验证码

### pig-gate-way模块pom.xml

```

<!--验证码 源码: https://github.com/pig-mesh/easy-captcha -->

<dependency>

<groupId>com.pig4cloud.plugin</groupId>

<artifactId>captcha-spring-boot-starter</artifactId>

<version>${captcha.version}</version>

</dependency>

```

`captcha-spring-boot-starter`中对验证码进行了配置,这里不详细展开说明。

### 基于webflux生成验证码

```

@Slf4j

@Configuration(proxyBeanMethods = false)

@RequiredArgsConstructor

public class RouterFunctionConfiguration {

private final ImageCodeHandler imageCodeHandler;

@Bean

public RouterFunction<ServerResponse> routerFunction() {

return RouterFunctions.route(

RequestPredicates.path("/code").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), imageCodeHandler);

}

}

```

`RouterFunctionConfiguration`用来注册一个路由和它的处理程序。

>proxyBeanMethods配置类是用来指定@Bean注解标注的方法是否使用代理,默认是true使用代理,直接从IOC容器之中取得对象;如果设置为false,也就是不使用注解,每次调用@Bean标注的方法获取到的对象和IOC容器中的都不一样,是一个新的对象。

>Spring 5.2.0 的版本,建议你的配置类均采用Lite模式去做,即显示设置proxyBeanMethods = false。Spring Boot在2.2.0版本(依赖于Spring 5.2.0)起就把它的所有的自动配置类的此属性改为了false,即@Configuration(proxyBeanMethods = false),提高Spring启动速度。

`RouterFunction`为我们应用程序添加一个新的路由,这个路由需要绑定一个`HandlerFunction`,做为它的处理程序,里面可以添加业务代码。

`ImageCodeHandler`

```

@Slf4j

@RequiredArgsConstructor

public class ImageCodeHandler implements HandlerFunction<ServerResponse> {

private static final Integer DEFAULT_IMAGE_WIDTH = 100;

private static final Integer DEFAULT_IMAGE_HEIGHT = 40;

private final RedisTemplate<String, Object> redisTemplate;

@Override

public Mono<ServerResponse> handle(ServerRequest serverRequest) {

ArithmeticCaptcha captcha = new ArithmeticCaptcha(DEFAULT_IMAGE_WIDTH, DEFAULT_IMAGE_HEIGHT);

String result = captcha.text();

// 保存验证码信息

Optional<String> randomStr = serverRequest.queryParam("randomStr");

redisTemplate.setKeySerializer(new StringRedisSerializer());

randomStr.ifPresent(s -> redisTemplate.opsForValue().set(CacheConstants.DEFAULT_CODE_KEY s, result,

SecurityConstants.CODE_TIME, TimeUnit.SECONDS));

// 转换流信息写出

FastByteArrayOutputStream os = new FastByteArrayOutputStream();

captcha.out(os);

return ServerResponse.status(HttpStatus.OK).contentType(MediaType.IMAGE_JPEG)

.body(BodyInserters.fromResource(new ByteArrayResource(os.toByteArray())));

}

}

```

## 校验验证码

### 网关配置

在`pig-gateway-dev.yml`中配置`ValidateCodeGatewayFilter`

![image](https://img2022.cnblogs.com/blog/1901531/202211/1901531-20221123100746821-1647892375.png)

### 校验验证码

```

public class ValidateCodeGatewayFilter extends AbstractGatewayFilterFactory {

@Override

public GatewayFilter apply(Object config) {

return (exchange, chain) -> {

ServerHttpRequest request = exchange.getRequest();

// 终端设置不校验, 直接向下执行

String[] clientInfos = WebUtils.getClientId(request);

if (filterIgnorePropertiesConfig.getClients().contains(clientInfos[0])) {

return chain.filter(exchange);

}

//校验验证码

checkCode(request);

return chain.filter(exchange);

};

}

}

```

`checkCode`方法

```

@SneakyThrows

private void checkCode(ServerHttpRequest request) {

String code = request.getQueryParams().getFirst("code");

if (CharSequenceUtil.isBlank(code)) {

throw new ValidateCodeException("验证码不能为空");

}

String randomStr = request.getQueryParams().getFirst("randomStr");

if (CharSequenceUtil.isBlank(randomStr)) {

randomStr = request.getQueryParams().getFirst(SecurityConstants.SMS_PARAMETER_NAME);

}

String key = CacheConstants.DEFAULT_CODE_KEY randomStr;

Object codeObj = redisTemplate.opsForValue().get(key);

if (ObjectUtil.isEmpty(codeObj) || !code.equals(codeObj)) {

throw new ValidateCodeException("验证码不合法");

}

redisTemplate.delete(key);

}

```

0 人点赞