package com.iplatform.base.controller;
|
|
import com.iplatform.base.ArgumentsConstants;
|
import com.iplatform.base.Constants;
|
import com.iplatform.base.SystemController;
|
import com.iplatform.base.captcha.BlockPuzzleCaptchaProvider;
|
import com.iplatform.base.captcha.JigsawCaptchaProvider;
|
import com.iplatform.base.captcha.JigsawResult;
|
import com.walker.infrastructure.utils.Base64;
|
import com.walker.infrastructure.utils.StringUtils;
|
import com.walker.web.CaptchaProvider;
|
import com.walker.web.CaptchaResult;
|
import com.walker.web.ResponseValue;
|
import com.walker.web.util.IdUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.util.FastByteArrayOutputStream;
|
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RestController;
|
|
import javax.imageio.ImageIO;
|
import java.io.IOException;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
/**
|
* 验证码生成接口,所有其他类型验证码生成器可以实现:<code>CaptchaProvider</code>,分离各种区别。
|
* @author 时克英
|
* @date 2022-11-07
|
*/
|
@RestController
|
public class CaptchaController extends SystemController {
|
|
private CaptchaProvider<CaptchaResult> imageCaptchaProvider;
|
// private CaptchaProvider<CaptchaResult> smsCaptchaProvider;
|
// 2023-04-06 拼图验证码提供者
|
private JigsawCaptchaProvider jigsawCaptchaProvider;
|
private BlockPuzzleCaptchaProvider blockPuzzleCaptchaProvider;
|
|
// 简单验证码类型: char, math
|
private String defaultCaptchaType = "math";
|
|
@Autowired
|
public CaptchaController(CaptchaProvider<CaptchaResult> imageCaptchaProvider
|
// , CaptchaProvider<CaptchaResult> smsCaptchaProvider
|
// , CacheProvider<String> captchaCacheProvider
|
, JigsawCaptchaProvider jigsawCaptchaProvider, BlockPuzzleCaptchaProvider blockPuzzleCaptchaProvider){
|
this.imageCaptchaProvider = imageCaptchaProvider;
|
// this.smsCaptchaProvider = smsCaptchaProvider;
|
// this.captchaCacheProvider = captchaCacheProvider;
|
this.jigsawCaptchaProvider = jigsawCaptchaProvider;
|
this.blockPuzzleCaptchaProvider = blockPuzzleCaptchaProvider;
|
}
|
|
@RequestMapping("/captcha/jigsaw/mobile")
|
public ResponseValue generateJigsawMobileCaptcha(){
|
String uuid = IdUtils.simpleUUID();
|
Map<String, Object> data = new HashMap<>(4);
|
data.put("uuid", uuid);
|
String verifyKey = Constants.CAPTCHA_CODE_PREFIX + uuid;
|
JigsawResult captchaResult = (JigsawResult)this.blockPuzzleCaptchaProvider.generateCaptcha(null);
|
if(captchaResult == null || captchaResult.getX() == 0){
|
return ResponseValue.error("拼图验证码生成错误, null");
|
}
|
// 写入验证码 x位置 到缓存中
|
this.getCaptchaCacheProvider().putCacheData(verifyKey, String.valueOf(captchaResult.getX()), 60);
|
logger.debug("写入拼图验证位置,x = {}", captchaResult.getX());
|
|
data.put("y", captchaResult.getY());
|
data.put("slider", captchaResult.getImageBlockBase64());
|
data.put("bg", captchaResult.getImageSourceBase64());
|
// data.put("captchaEnabled", true);
|
return ResponseValue.success(data);
|
}
|
|
/**
|
* 验证拼图位置
|
* @param token 传入的uuid
|
* @param x 横坐标位置
|
* @return
|
* @date 2023-04-07
|
*/
|
@PostMapping("/captcha/jigsaw_validate")
|
public ResponseValue validateJigsaw(String token, String x){
|
if(StringUtils.isEmpty(token) || StringUtils.isEmpty(x)){
|
return ResponseValue.error("未接收到验证输入信息!");
|
}
|
// String verifyKey = Constants.CAPTCHA_CODE_PREFIX + token;
|
// String xString = this.captchaCacheProvider.getCacheData(verifyKey);
|
// if(StringUtils.isEmpty(xString)){
|
// throw new IllegalStateException("拼图验证信息已失效!");
|
// }
|
|
CaptchaResult captchaResult = new CaptchaResult();
|
captchaResult.setUuid(token);
|
captchaResult.setCode(x);
|
|
Map<String, String> data = new HashMap<>(4);
|
|
boolean success = this.jigsawCaptchaProvider.validateCaptcha(captchaResult);
|
if(!success){
|
// 验证失败
|
data.put("verify", "-1");
|
return ResponseValue.success(data);
|
}
|
|
data.put("verify", "1");
|
data.put("x", x);
|
data.put("uuid", token); // uuid也要返回界面
|
return ResponseValue.success(data);
|
}
|
|
/**
|
* 获取拼图验证码信息。
|
* @return
|
* @date 2023-04-06
|
*/
|
@RequestMapping("/captcha/jigsaw")
|
public ResponseValue generateJigsawCaptcha(){
|
// SimpleKaptchaProvider provider = null;
|
boolean captchaEnabled = this.getArgumentVariable(ArgumentsConstants.KEY_SECURITY_CAPTCHA_ENABLED).getBooleanValue();
|
|
String uuid = IdUtils.simpleUUID();
|
Map<String, Object> data = new HashMap<>(4);
|
data.put("uuid", uuid);
|
|
if(captchaEnabled){
|
String verifyKey = Constants.CAPTCHA_CODE_PREFIX + uuid;
|
JigsawResult captchaResult = (JigsawResult)this.jigsawCaptchaProvider.generateCaptcha(null);
|
if(captchaResult == null || captchaResult.getX() == 0){
|
return ResponseValue.error("拼图验证码生成错误, null");
|
}
|
// 写入验证码 x位置 到缓存中
|
this.getCaptchaCacheProvider().putCacheData(verifyKey, String.valueOf(captchaResult.getX()), 60);
|
logger.debug("写入拼图验证位置,x = {}", captchaResult.getX());
|
|
data.put("y", captchaResult.getY());
|
data.put("slider", captchaResult.getImageBlockBase64());
|
data.put("bg", captchaResult.getImageSourceBase64());
|
data.put("captchaEnabled", true);
|
return ResponseValue.success(data);
|
|
} else {
|
// 没有验证码方式
|
data.put("captchaEnabled", false);
|
return ResponseValue.success(data);
|
}
|
}
|
|
/**
|
* 生成短信验证码,放入缓存。
|
* @param phoneNumber
|
* @return
|
* @date 2023-01-27
|
*/
|
// @RequestMapping("/captchaSms")
|
@RequestMapping("/captcha/sms")
|
public ResponseValue generateSmsCaptcha(String phoneNumber){
|
if(StringUtils.isEmpty(phoneNumber)){
|
return ResponseValue.error("请输入手机号");
|
}
|
/*String uuid = IdUtils.simpleUUID();
|
Map<String, Object> data = new HashMap<>(4);
|
data.put("uuid", uuid);
|
String verifyKey = Constants.CAPTCHA_CODE_PREFIX + uuid;
|
CaptchaResult captchaResult = this.getSmsCaptchaProvider().generateCaptcha(phoneNumber);
|
if(captchaResult == null){
|
return ResponseValue.error("短信验证码生成错误, null");
|
}
|
// 写入验证码 key 和 code 到缓存中
|
this.getCaptchaCacheProvider().putCacheData(verifyKey, captchaResult.getCode(), 120);
|
if(this.logger.isDebugEnabled()){
|
this.logger.debug("生成短信验证码:{}, uuid:{}", captchaResult.getCode(), uuid);
|
}*/
|
try{
|
Map<String, Object> data = this.sendSmsCodeValidation(phoneNumber);
|
return ResponseValue.success(data);
|
|
} catch (Exception ex){
|
return ResponseValue.error(ex.getMessage());
|
}
|
}
|
|
/**
|
* PC端登录,生成简单的图像验证码
|
* @return
|
* @date 2022-10-11
|
*/
|
// @GetMapping("/captchaImage")
|
@GetMapping("/captcha/image")
|
public ResponseValue generateImageCaptcha(){
|
|
// boolean captchaEnabled = VariableConstants.CAPTCHA_ENABLED;
|
boolean captchaEnabled = this.getArgumentVariable(ArgumentsConstants.KEY_SECURITY_CAPTCHA_ENABLED).getBooleanValue();
|
|
String uuid = IdUtils.simpleUUID();
|
Map<String, Object> data = new HashMap<>(4);
|
data.put("uuid", uuid);
|
|
if(captchaEnabled){
|
String verifyKey = Constants.CAPTCHA_CODE_PREFIX + uuid;
|
CaptchaResult captchaResult = this.imageCaptchaProvider.generateCaptcha(this.defaultCaptchaType);
|
if(captchaResult == null){
|
return ResponseValue.error("验证码生成错误, null");
|
}
|
|
// 写入验证码 key 和 code 到缓存中
|
this.getCaptchaCacheProvider().putCacheData(verifyKey, captchaResult.getCode(), 120);
|
if(this.logger.isDebugEnabled()){
|
this.logger.debug("生成图像验证码:{}, uuid:{}", captchaResult.getCode(), uuid);
|
}
|
|
// 转换流信息写出
|
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
|
try {
|
ImageIO.write(captchaResult.getImage(), "jpg", os);
|
data.put("img", new String(Base64.encode(os.toByteArray()), StringUtils.DEFAULT_CHARSET_UTF8));
|
// data.put("img", CaptchaUtils.encode(os.toByteArray()));
|
data.put("captchaEnabled", true);
|
return ResponseValue.success(data);
|
}
|
catch (IOException e) {
|
return ResponseValue.error(e.getMessage());
|
}
|
|
} else {
|
// 没有验证码方式
|
data.put("captchaEnabled", false);
|
return ResponseValue.success(data);
|
}
|
}
|
|
/**
|
* 在slider滑块验证,sms短信验证时,不需要实际验证码,仅返回uuid。
|
* @return
|
* @date 2023-03-22
|
*/
|
@GetMapping("/captcha/none")
|
public ResponseValue generateCaptchaNone(){
|
String uuid = IdUtils.simpleUUID();
|
Map<String, Object> data = new HashMap<>(4);
|
data.put("uuid", uuid);
|
return ResponseValue.success(data);
|
}
|
}
|