mirror of
https://github.com/dromara/tianai-captcha.git
synced 2026-05-07 06:04:34 +08:00
fix: 修复点选验证码图片文字缩放的bug
This commit is contained in:
@@ -0,0 +1,233 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
必须用中文回复我
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
tianai-captcha (天爱验证码/TAC) is a Java-based behavioral CAPTCHA library supporting multiple verification types:
|
||||||
|
- **SLIDER**: Slide-to-fit puzzle captcha
|
||||||
|
- **ROTATE**: Rotation verification captcha
|
||||||
|
- **CONCAT**: Slide-to-restore captcha
|
||||||
|
- **WORD_IMAGE_CLICK**: Text-click verification captcha
|
||||||
|
|
||||||
|
The project is a multi-module Maven project with Java 8 compatibility.
|
||||||
|
|
||||||
|
## Build Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build the entire project (skips tests by default)
|
||||||
|
mvn clean install
|
||||||
|
|
||||||
|
# Build without skipping tests
|
||||||
|
mvn clean install -DskipTests=false
|
||||||
|
|
||||||
|
# Build specific module
|
||||||
|
cd tianai-captcha
|
||||||
|
mvn clean install
|
||||||
|
|
||||||
|
# Package for deployment
|
||||||
|
mvn clean package
|
||||||
|
|
||||||
|
# Generate javadoc
|
||||||
|
mvn javadoc:javadoc
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run all tests
|
||||||
|
mvn test
|
||||||
|
|
||||||
|
# Run tests for specific module
|
||||||
|
cd tianai-captcha
|
||||||
|
mvn test
|
||||||
|
|
||||||
|
# Run a specific test class
|
||||||
|
mvn test -Dtest=TACBuilderTest
|
||||||
|
|
||||||
|
# Run a specific test method
|
||||||
|
mvn test -Dtest=TACBuilderTest#testMethod
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
### Modules
|
||||||
|
|
||||||
|
1. **tianai-captcha** (core module)
|
||||||
|
- Core captcha generation and validation logic
|
||||||
|
- Generator implementations for each captcha type
|
||||||
|
- Resource management system
|
||||||
|
- Cache and storage abstractions
|
||||||
|
|
||||||
|
2. **tianai-captcha-springboot-starter**
|
||||||
|
- Spring Boot auto-configuration
|
||||||
|
- Redis integration support
|
||||||
|
- Configuration properties binding
|
||||||
|
|
||||||
|
3. **tianai-captcha-solon-plugin**
|
||||||
|
- Solon framework integration
|
||||||
|
|
||||||
|
4. **tianai-captcha-web-sdk**
|
||||||
|
- Frontend JavaScript SDK
|
||||||
|
|
||||||
|
## Core Architecture
|
||||||
|
|
||||||
|
### Key Components
|
||||||
|
|
||||||
|
**ImageCaptchaApplication** (cloud.tianai.captcha.application.ImageCaptchaApplication)
|
||||||
|
- Main entry point for captcha operations
|
||||||
|
- Handles captcha generation via `generateCaptcha(type)`
|
||||||
|
- Handles validation via `matching(id, matchParam)`
|
||||||
|
- Manages lifecycle of generators, validators, and cache
|
||||||
|
|
||||||
|
**TACBuilder** (cloud.tianai.captcha.application.TACBuilder)
|
||||||
|
- Builder pattern for constructing ImageCaptchaApplication
|
||||||
|
- Fluent API for configuration
|
||||||
|
- Key methods:
|
||||||
|
- `addDefaultTemplate()`: Load built-in templates
|
||||||
|
- `addResource(type, resource)`: Add background images
|
||||||
|
- `addTemplate(type, resourceMap)`: Add custom templates
|
||||||
|
- `addFont(resource)`: Add fonts for WORD_IMAGE_CLICK
|
||||||
|
- `cached(size, waitTime, period, expireTime)`: Enable pre-generation cache
|
||||||
|
- `setCacheStore(store)`: Set cache implementation (local or distributed)
|
||||||
|
- `setResourceStore(store)`: Set resource storage
|
||||||
|
- `setTransform(transform)`: Set image transformation (default: Base64)
|
||||||
|
|
||||||
|
### Generator Layer
|
||||||
|
|
||||||
|
**MultiImageCaptchaGenerator** (cloud.tianai.captcha.generator.impl.MultiImageCaptchaGenerator)
|
||||||
|
- Delegates to specific generators based on captcha type
|
||||||
|
- Manages resource loading and image transformation
|
||||||
|
|
||||||
|
**Specific Generators**:
|
||||||
|
- `StandardSliderImageCaptchaGenerator`: Generates slider puzzles
|
||||||
|
- `StandardRotateImageCaptchaGenerator`: Generates rotation captchas
|
||||||
|
- `StandardConcatImageCaptchaGenerator`: Generates slide-to-restore captchas
|
||||||
|
- `StandardWordClickImageCaptchaGenerator`: Generates text-click captchas
|
||||||
|
|
||||||
|
**CacheImageCaptchaGenerator** (cloud.tianai.captcha.generator.impl.CacheImageCaptchaGenerator)
|
||||||
|
- Wrapper that pre-generates captchas for improved performance
|
||||||
|
- Configurable cache size and refresh intervals
|
||||||
|
|
||||||
|
### Validator Layer
|
||||||
|
|
||||||
|
**ImageCaptchaValidator** (cloud.tianai.captcha.validator.ImageCaptchaValidator)
|
||||||
|
- Interface for captcha validation logic
|
||||||
|
- Default implementation: `SimpleImageCaptchaValidator`
|
||||||
|
|
||||||
|
**BasicCaptchaTrackValidator** (cloud.tianai.captcha.validator.impl.BasicCaptchaTrackValidator)
|
||||||
|
- Validates mouse/touch track data
|
||||||
|
- Checks for suspicious behavior patterns
|
||||||
|
|
||||||
|
### Resource Management
|
||||||
|
|
||||||
|
**ResourceStore** (cloud.tianai.captcha.resource.ResourceStore)
|
||||||
|
- Abstraction for storing captcha resources (images, templates)
|
||||||
|
- Implementations:
|
||||||
|
- `LocalMemoryResourceStore`: In-memory storage
|
||||||
|
- Custom implementations for distributed scenarios
|
||||||
|
|
||||||
|
**ImageCaptchaResourceManager** (cloud.tianai.captcha.resource.ImageCaptchaResourceManager)
|
||||||
|
- Manages resource loading and retrieval
|
||||||
|
- Default implementation: `DefaultImageCaptchaResourceManager`
|
||||||
|
|
||||||
|
**Resource** (cloud.tianai.captcha.resource.common.model.dto.Resource)
|
||||||
|
- Represents a resource with type and location
|
||||||
|
- Types: "classpath", "file", "url"
|
||||||
|
|
||||||
|
### Cache Layer
|
||||||
|
|
||||||
|
**CacheStore** (cloud.tianai.captcha.cache.CacheStore)
|
||||||
|
- Abstraction for caching captcha data
|
||||||
|
- Implementations:
|
||||||
|
- `LocalCacheStore`: Local in-memory cache
|
||||||
|
- Redis-based implementation in Spring Boot starter
|
||||||
|
|
||||||
|
### Image Transformation
|
||||||
|
|
||||||
|
**ImageTransform** (cloud.tianai.captcha.generator.ImageTransform)
|
||||||
|
- Converts generated images to desired format
|
||||||
|
- Default: `Base64ImageTransform` (JPG for background, PNG for template)
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Non-Spring Projects
|
||||||
|
|
||||||
|
Use TACBuilder to configure:
|
||||||
|
|
||||||
|
```java
|
||||||
|
ImageCaptchaApplication app = TACBuilder.builder()
|
||||||
|
.addDefaultTemplate()
|
||||||
|
.addResource("SLIDER", new Resource("classpath", "path/to/image.jpg"))
|
||||||
|
.cached(20, 5000, 2000, 120000L)
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Spring Boot Projects
|
||||||
|
|
||||||
|
Configure via application.yml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
captcha:
|
||||||
|
prefix: captcha # Cache key prefix
|
||||||
|
expire:
|
||||||
|
default: 120000 # Default expiration (ms)
|
||||||
|
WORD_IMAGE_CLICK: 180000 # Type-specific expiration
|
||||||
|
init-default-resource: false # Load built-in resources
|
||||||
|
local-cache-enabled: true # Enable pre-generation cache
|
||||||
|
local-cache-size: 20 # Cache size
|
||||||
|
local-cache-wait-time: 5000 # Wait time on cache miss (ms)
|
||||||
|
local-cache-period: 2000 # Cache refresh interval (ms)
|
||||||
|
font-path: # Font files for WORD_IMAGE_CLICK
|
||||||
|
- classpath:font/simhei.ttf
|
||||||
|
```
|
||||||
|
|
||||||
|
## Important Constants
|
||||||
|
|
||||||
|
**CaptchaTypeConstant** (cloud.tianai.captcha.common.constant.CaptchaTypeConstant)
|
||||||
|
- `SLIDER`: Slide-to-fit captcha
|
||||||
|
- `ROTATE`: Rotation captcha
|
||||||
|
- `CONCAT`: Slide-to-restore captcha
|
||||||
|
- `WORD_IMAGE_CLICK`: Text-click captcha
|
||||||
|
|
||||||
|
**ParamKeyEnum** (cloud.tianai.captcha.generator.common.model.dto.ParamKeyEnum)
|
||||||
|
- `TOLERANT`: Configurable tolerance value for validation (added in recent commit)
|
||||||
|
|
||||||
|
## Key Data Flow
|
||||||
|
|
||||||
|
### Generation Flow
|
||||||
|
1. Client calls `ImageCaptchaApplication.generateCaptcha(type)`
|
||||||
|
2. `MultiImageCaptchaGenerator` selects appropriate generator
|
||||||
|
3. Generator loads resources via `ImageCaptchaResourceManager`
|
||||||
|
4. Generator creates captcha with random parameters
|
||||||
|
5. `ImageTransform` converts images to Base64 (or custom format)
|
||||||
|
6. Captcha data cached in `CacheStore` with unique ID
|
||||||
|
7. Returns `ImageCaptchaVO` with ID and image data
|
||||||
|
|
||||||
|
### Validation Flow
|
||||||
|
1. Client submits ID and track data via `matching(id, matchParam)`
|
||||||
|
2. Application retrieves cached captcha data by ID
|
||||||
|
3. `ImageCaptchaValidator` validates track against expected answer
|
||||||
|
4. `BasicCaptchaTrackValidator` checks track behavior patterns
|
||||||
|
5. Returns `ApiResponse` with success/failure status
|
||||||
|
|
||||||
|
## Extension Points
|
||||||
|
|
||||||
|
- **Custom Generators**: Implement `ImageCaptchaGenerator` interface
|
||||||
|
- **Custom Validators**: Implement `ImageCaptchaValidator` interface
|
||||||
|
- **Custom Cache**: Implement `CacheStore` (e.g., Redis, Memcached)
|
||||||
|
- **Custom Resources**: Implement `ResourceStore` for centralized resource management
|
||||||
|
- **Custom Transform**: Implement `ImageTransform` for different image formats
|
||||||
|
- **Interceptors**: Implement `CaptchaInterceptor` for pre/post processing
|
||||||
|
|
||||||
|
## Recent Changes
|
||||||
|
|
||||||
|
- Added support for Spring Boot 4 (commit: db0603a, 7c8730f)
|
||||||
|
- Fixed resource leak issues (commits: 16e517c, 29279e8)
|
||||||
|
- Added configurable tolerance value via `ParamKeyEnum.TOLERANT` (commit: a4f8a99)
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- Online Demo: http://captcha.tianai.cloud
|
||||||
|
- Online Documentation: http://doc.captcha.tianai.cloud
|
||||||
|
- License: MulanPSL-2.0
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>1.5.3</revision>
|
<revision>1.5.4</revision>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
<!-- 打包跳过单元测试 -->
|
<!-- 打包跳过单元测试 -->
|
||||||
<skipTests>true</skipTests>
|
<skipTests>true</skipTests>
|
||||||
|
|||||||
+2
-2
@@ -65,7 +65,7 @@ public abstract class AbstractClickImageCaptchaGenerator extends AbstractImageCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 随机获取点击图片
|
// 随机获取点击图片
|
||||||
ClickImageCheckDefinition.ImgWrapper imgWrapper = getClickImg(param, clickResource, null);
|
ClickImageCheckDefinition.ImgWrapper imgWrapper = getClickImg(param, clickResource, null, bgImage);
|
||||||
BufferedImage image = imgWrapper.getImage();
|
BufferedImage image = imgWrapper.getImage();
|
||||||
// 增加功能,是否需要扭曲图片
|
// 增加功能,是否需要扭曲图片
|
||||||
image = obfuscateImage(image, param);
|
image = obfuscateImage(image, param);
|
||||||
@@ -143,7 +143,7 @@ public abstract class AbstractClickImageCaptchaGenerator extends AbstractImageCa
|
|||||||
* @param tip 提示数据,根据改数据生成图片
|
* @param tip 提示数据,根据改数据生成图片
|
||||||
* @return ImgWrapper
|
* @return ImgWrapper
|
||||||
*/
|
*/
|
||||||
public abstract ClickImageCheckDefinition.ImgWrapper getClickImg(GenerateParam param, Resource tip, Color randomColor);
|
public abstract ClickImageCheckDefinition.ImgWrapper getClickImg(GenerateParam param, Resource tip, Color randomColor, BufferedImage bgImage);
|
||||||
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
+2
-2
@@ -92,7 +92,7 @@ public class StandardWordClickImageCaptchaGenerator extends AbstractClickImageCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClickImageCheckDefinition.ImgWrapper getClickImg(GenerateParam param, Resource tip, Color randomColor) {
|
public ClickImageCheckDefinition.ImgWrapper getClickImg(GenerateParam param, Resource tip, Color randomColor, BufferedImage bgImage) {
|
||||||
if (randomColor == null) {
|
if (randomColor == null) {
|
||||||
ThreadLocalRandom random = ThreadLocalRandom.current();
|
ThreadLocalRandom random = ThreadLocalRandom.current();
|
||||||
randomColor = CaptchaImageUtils.getRandomColor(random);
|
randomColor = CaptchaImageUtils.getRandomColor(random);
|
||||||
@@ -100,7 +100,7 @@ public class StandardWordClickImageCaptchaGenerator extends AbstractClickImageCa
|
|||||||
// 随机角度
|
// 随机角度
|
||||||
int randomDeg = randomInt(0, 85);
|
int randomDeg = randomInt(0, 85);
|
||||||
// 缩放
|
// 缩放
|
||||||
double factor = 600d;
|
double factor = (double) bgImage.getWidth(null) / 600d;
|
||||||
|
|
||||||
FontWrapper fontWrapper = randomFont(param);
|
FontWrapper fontWrapper = randomFont(param);
|
||||||
Font font = fontWrapper.getFont((float) (FontWrapper.DEFAULT_FONT_SIZE * factor));
|
Font font = fontWrapper.getFont((float) (FontWrapper.DEFAULT_FONT_SIZE * factor));
|
||||||
|
|||||||
@@ -14,48 +14,100 @@ import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
|||||||
import cloud.tianai.captcha.resource.common.model.dto.ResourceMap;
|
import cloud.tianai.captcha.resource.common.model.dto.ResourceMap;
|
||||||
import cloud.tianai.captcha.resource.impl.LocalMemoryResourceStore;
|
import cloud.tianai.captcha.resource.impl.LocalMemoryResourceStore;
|
||||||
import cloud.tianai.captcha.resource.impl.provider.ClassPathResourceProvider;
|
import cloud.tianai.captcha.resource.impl.provider.ClassPathResourceProvider;
|
||||||
|
import cloud.tianai.captcha.validator.common.model.dto.ImageCaptchaTrack;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
|
import static cloud.tianai.captcha.common.constant.CommonConstant.DEFAULT_TAG;
|
||||||
|
import static cloud.tianai.captcha.generator.impl.StandardSliderImageCaptchaGenerator.TEMPLATE_ACTIVE_IMAGE_NAME;
|
||||||
|
import static cloud.tianai.captcha.generator.impl.StandardSliderImageCaptchaGenerator.TEMPLATE_FIXED_IMAGE_NAME;
|
||||||
|
|
||||||
|
|
||||||
public class TACBuilderTest {
|
public class TACBuilderTest {
|
||||||
|
|
||||||
|
|
||||||
|
public void test() {
|
||||||
|
ResourceMap template1 = new ResourceMap(DEFAULT_TAG, 2);
|
||||||
|
// 滑块轮廓图片
|
||||||
|
template1.put(TEMPLATE_ACTIVE_IMAGE_NAME, new Resource("classpath", "META-INF/cut-image/template/slider_1/active.png"));
|
||||||
|
// 滑块凹槽图片
|
||||||
|
template1.put(TEMPLATE_FIXED_IMAGE_NAME, new Resource("classpath", "META-INF/cut-image/template/slider_1/fixed.png"));
|
||||||
|
|
||||||
|
// 给旋转验证码配置模板
|
||||||
|
ResourceMap template2 = new ResourceMap(DEFAULT_TAG, 2);
|
||||||
|
// 旋转验证码轮廓图片
|
||||||
|
template2.put(TEMPLATE_ACTIVE_IMAGE_NAME, new Resource("classpath", "META-INF/cut-image/template/rotate_1/active.png"));
|
||||||
|
// 旋转验证码凹槽图片
|
||||||
|
template2.put(TEMPLATE_FIXED_IMAGE_NAME, new Resource("classpath", "META-INF/cut-image/template/rotate_1/fixed.png"));
|
||||||
|
|
||||||
|
ImageCaptchaApplication application = TACBuilder.builder()
|
||||||
|
// 设置资源存储器,默认是 LocalMemoryResourceStore
|
||||||
|
.setResourceStore(new LocalMemoryResourceStore())
|
||||||
|
// 配置模板
|
||||||
|
.addTemplate(CaptchaTypeConstant.SLIDER,template1)
|
||||||
|
.addTemplate(CaptchaTypeConstant.ROTATE,template2)
|
||||||
|
// ...其他配置
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws InterruptedException {
|
public static void main(String[] args) throws InterruptedException {
|
||||||
Font font= null;
|
Font font = null;
|
||||||
// ResourceMap template1 = new ResourceMap("default", 4);
|
// ResourceMap template1 = new ResourceMap("default", 4);
|
||||||
// template1.put(StandardSliderImageCaptchaGenerator.TEMPLATE_ACTIVE_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, "/active.png"));
|
// template1.put(StandardSliderImageCaptchaGenerator.TEMPLATE_ACTIVE_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, "/active.png"));
|
||||||
// template1.put(StandardSliderImageCaptchaGenerator.TEMPLATE_FIXED_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, "/fixed.png"));
|
// template1.put(StandardSliderImageCaptchaGenerator.TEMPLATE_FIXED_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, "/fixed.png"));
|
||||||
|
|
||||||
ImageCaptchaApplication application = TACBuilder.builder()
|
ImageCaptchaApplication application = TACBuilder.builder()
|
||||||
|
// 设置资源存储器,默认是 LocalMemoryResourceStore
|
||||||
.setResourceStore(new LocalMemoryResourceStore())
|
.setResourceStore(new LocalMemoryResourceStore())
|
||||||
// 加载系统自带的默认资源
|
// 加载系统自带的默认资源(系统内置了几个滑块验证码缺口模板图,调用此函数加载)
|
||||||
.addDefaultTemplate()
|
.addDefaultTemplate()
|
||||||
// 设置验证码过期时间
|
// 设置验证码过期时间, 单位毫秒, default 是默认验证码过期时间,当前设置为10秒,
|
||||||
|
// 可以自定义某些验证码类型单独的过期时间, 比如把点选验证码的过期时间设置为60秒
|
||||||
.expire("default", 10000L)
|
.expire("default", 10000L)
|
||||||
.expire("WORD_IMAGE_CLICK", 60000L)
|
.expire(CaptchaTypeConstant.WORD_IMAGE_CLICK, 60000L)
|
||||||
// 设置拦截器
|
// 设置拦截器,默认是 EmptyCaptchaInterceptor.INSTANCE
|
||||||
.setInterceptor(EmptyCaptchaInterceptor.INSTANCE)
|
.setInterceptor(EmptyCaptchaInterceptor.INSTANCE)
|
||||||
// 添加验证码背景图片
|
// 添加验证码背景图片
|
||||||
.addResource("SLIDER", new Resource("classpath", "META-INF/cut-image/resource/1.jpg"))
|
// arg1 验证码类型(SLIDER、WORD_IMAGE_CLICK、ROTATE、CONCAT),
|
||||||
.addResource("WORD_IMAGE_CLICK", new Resource("classpath", "META-INF/cut-image/resource/1.jpg"))
|
// arg2 验证码背景图片资源
|
||||||
.addResource("ROTATE", new Resource("classpath", "META-INF/cut-image/resource/1.jpg"))
|
.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "META-INF/cut-image/resource/1.jpg"))
|
||||||
|
.addResource(CaptchaTypeConstant.WORD_IMAGE_CLICK, new Resource("classpath", "META-INF/cut-image/resource/1.jpg"))
|
||||||
|
.addResource(CaptchaTypeConstant.ROTATE, new Resource("classpath", "META-INF/cut-image/resource/1.jpg"))
|
||||||
|
.addResource(CaptchaTypeConstant.CONCAT, new Resource("classpath", "META-INF/cut-image/resource/1.jpg"))
|
||||||
// 添加验证码模板图片
|
// 添加验证码模板图片
|
||||||
// .addTemplate("SLIDER",template1)
|
// .addTemplate("SLIDER",template1)
|
||||||
// 设置缓冲器,可提前生成验证码,用于增加并发性
|
// 设置缓存器,可提前生成验证码,用于增加并发性,可以不设置,默认是不开启缓存
|
||||||
.cached(10, 1000, 5000, 10000L)
|
.cached(10, 1000, 5000, 10000L)
|
||||||
// 添加字体包,用于给文字点选验证码提供字体
|
// 添加字体包,用于给文字点选验证码提供字体
|
||||||
.addFont(new Resource("file", "C:\\Users\\Thinkpad\\Desktop\\captcha\\手写字体\\ttf\\千图小兔体.ttf"))
|
.addFont(new Resource("file", "C:\\Users\\Thinkpad\\Desktop\\captcha\\手写字体\\ttf\\千图小兔体.ttf"))
|
||||||
// 设置缓存存储器,如果要支持分布式,需要把这里改成分布式缓存,比如通过redis实现的 CacheStore 缓存
|
// 设置缓存存储器,如果要支持分布式,需要把这里改成分布式缓存,比如通过redis实现的 CacheStore 缓存
|
||||||
.setCacheStore(new LocalCacheStore())
|
.setCacheStore(new LocalCacheStore())
|
||||||
// 设置资源存储器,如果想在分布式环境或者想统一管理以及扩展 实现 ResourceStore 接口,自定义
|
|
||||||
// .setResourceStore(new LocalMemoryResourceStore())
|
|
||||||
// 图片转换器,默认是将图片转换成base64格式, 背景图为jpg, 模板图为png, 如果想要扩展,可替换成自己实现的
|
// 图片转换器,默认是将图片转换成base64格式, 背景图为jpg, 模板图为png, 如果想要扩展,可替换成自己实现的
|
||||||
.setTransform(new Base64ImageTransform())
|
.setTransform(new Base64ImageTransform())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
while (true){
|
while (true) {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
ApiResponse<ImageCaptchaVO> response = application.generateCaptcha("SLIDER");
|
|
||||||
|
// 生成验证码
|
||||||
|
// arg1 验证码类型(SLIDER、WORD_IMAGE_CLICK、ROTATE、CONCAT)
|
||||||
|
// response 为生成的验证码数据,可直接返回给前端
|
||||||
|
ApiResponse<ImageCaptchaVO> response = application.generateCaptcha(CaptchaTypeConstant.SLIDER);
|
||||||
|
|
||||||
|
|
||||||
|
// 校验验证码
|
||||||
|
// captchaId 和 track 数据应该是前端传来的验证数据
|
||||||
|
String captchaId = "";
|
||||||
|
ImageCaptchaTrack track = null;
|
||||||
|
ApiResponse<?> matching = application.matching(captchaId, track);
|
||||||
|
|
||||||
|
|
||||||
|
if (matching.isSuccess()) {
|
||||||
|
System.out.println("校验成功");
|
||||||
|
} else {
|
||||||
|
System.out.println("校验失败:" + matching.getMsg());
|
||||||
|
}
|
||||||
|
|
||||||
System.out.println("耗时:" + (System.currentTimeMillis() - start));
|
System.out.println("耗时:" + (System.currentTimeMillis() - start));
|
||||||
// System.out.println(response);
|
// System.out.println(response);
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
|
|||||||
Reference in New Issue
Block a user