!170 删除功能 新增验证码方法

删除功能 新增验证码方法
This commit is contained in:
高雄
2023-07-21 09:52:27 +00:00
committed by 陈精华
parent c54a5e9f1a
commit 294dcb1994
8 changed files with 266 additions and 7 deletions

View File

@@ -130,6 +130,8 @@ tif.preview.type = ${KK_TIF_PREVIEW_TYPE:tif}
beian = ${KK_BEIAN:default}
#禁止上传类型
prohibit = ${KK_PROHIBIT:exe,dll,dat}
#启用验证码删除文件 默认关闭
delete.captcha= ${KK_DELETE_CAPTCHA:false}
#删除密码
delete.password = ${KK_DELETE_PASSWORD:123456}
#删除 转换后OFFICECADTIFF压缩包源文件 默认开启 节约磁盘空间

View File

@@ -50,6 +50,7 @@ public class ConfigConstants {
private static String officeTypeWeb;
private static String cadPreviewType;
private static Boolean deleteSourceFile;
private static Boolean deleteCaptcha;
public static final String DEFAULT_CACHE_ENABLED = "true";
public static final String DEFAULT_TXT_TYPE = "txt,html,htm,asp,jsp,xml,json,properties,md,gitignore,log,java,py,c,cpp,sql,sh,bat,m,bas,prg,cmd";
@@ -78,6 +79,7 @@ public class ConfigConstants {
public static final String DEFAULT_PDF2_JPG_DPI = "105";
public static final String DEFAULT_OFFICE_TYPE_WEB = "web";
public static final String DEFAULT_DELETE_SOURCE_FILE = "true";
public static final String DEFAULT_DELETE_CAPTCHA = "false";
public static Boolean isCacheEnabled() {
return cacheEnabled;
@@ -447,7 +449,9 @@ public class ConfigConstants {
setDeleteSourceFileValue(deleteSourceFile);
}
public static void setDeleteSourceFileValue(Boolean deleteSourceFile) {
ConfigConstants.deleteSourceFile = deleteSourceFile;
}
public static String getCadPreviewType() {
return cadPreviewType;
@@ -462,8 +466,16 @@ public class ConfigConstants {
ConfigConstants.cadPreviewType = cadPreviewType;
}
public static void setDeleteSourceFileValue(Boolean deleteSourceFile) {
ConfigConstants.deleteSourceFile = deleteSourceFile;
public static Boolean getDeleteCaptcha() {
return deleteCaptcha;
}
@Value("${delete.captcha:false}")
public void setDeleteCaptcha(Boolean deleteCaptcha) {
setDeleteCaptchaValue(deleteCaptcha);
}
public static void setDeleteCaptchaValue(Boolean deleteCaptcha) {
ConfigConstants.deleteCaptcha = deleteCaptcha;
}
}

View File

@@ -62,6 +62,7 @@ public class ConfigRefreshComponent {
String officeTypeWeb;
String cadPreviewType;
boolean deleteSourceFile;
boolean deleteCaptcha;
while (true) {
FileReader fileReader = new FileReader(configFilePath);
BufferedReader bufferedReader = new BufferedReader(fileReader);
@@ -94,6 +95,7 @@ public class ConfigRefreshComponent {
pdf2JpgDpi = Integer.parseInt(properties.getProperty("pdf2jpg.dpi", ConfigConstants.DEFAULT_PDF2_JPG_DPI));
officeTypeWeb = properties.getProperty("office.type.web", ConfigConstants.DEFAULT_OFFICE_TYPE_WEB);
deleteSourceFile = Boolean.parseBoolean(properties.getProperty("delete.source.file", ConfigConstants.DEFAULT_DELETE_SOURCE_FILE));
deleteCaptcha = Boolean.parseBoolean(properties.getProperty("delete.captcha", ConfigConstants.DEFAULT_DELETE_CAPTCHA));
prohibitArray = prohibit.split(",");
ConfigConstants.setCacheEnabledValueValue(cacheEnabled);
@@ -121,6 +123,7 @@ public class ConfigRefreshComponent {
ConfigConstants.setPdf2JpgDpiValue(pdf2JpgDpi);
ConfigConstants.setOfficeTypeWebValue(officeTypeWeb);
ConfigConstants.setDeleteSourceFileValue(deleteSourceFile);
ConfigConstants.setDeleteCaptchaValue(deleteCaptcha);
setWatermarkConfig(properties);
bufferedReader.close();
fileReader.close();

View File

@@ -0,0 +1,90 @@
package cn.keking.utils;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class RandomValidateCodeUtil {
private static final int width = 100;// 定义图片的width
private static final int height = 30;// 定义图片的height
private static final int codeCount = 4;// 定义图片上显示验证码的个数
private static final int xx = 18;
private static final int fontHeight = 28;
private static final int codeY = 27;
private static final char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q', 'R','T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a','b','c','d','e','f','g','h','j','k','m','n','p','q','r','s','t','u','v','w','x','y', '2', '3', '4','5', '6', '7', '8', '9' };
/**
* 生成一个map集合
* code为生成的验证码
* codePic为生成的验证码BufferedImage对象
*/
public static Map<String,Object> generateCodeAndPic(String ip, String sessionCode, int lx) {
// 定义图像buffer
BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// Graphics2D gd = buffImg.createGraphics();
// Graphics2D gd = (Graphics2D) buffImg.getGraphics();
Graphics gd = buffImg.getGraphics();
// 创建一个随机数生成器类
Random random = new Random();
// 将图像填充为白色
gd.setColor(Color.WHITE);
gd.fillRect(0, 0, width, height);
// 创建字体,字体的大小应该根据图片的高度来定。
Font font = new Font("Times New Roman", Font.BOLD, fontHeight);
// 设置字体。
gd.setFont(font);
// 画边框。
gd.setColor(Color.BLACK);
gd.drawRect(0, 0, width - 1, height - 1);
// 随机产生40条干扰线使图象中的认证码不易被其它程序探测到。
gd.setColor(Color.BLACK);
for (int i = 0; i < 30; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
gd.drawLine(x, y, x + xl, y + yl);
}
StringBuffer randomCode = new StringBuffer();
Map<String,Object> map = new HashMap<>();
// randomCode用于保存随机产生的验证码以便用户登录后进行验证。
int red, green, blue;
if (lx ==1){
// 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。
red = random.nextInt(255);
green = random.nextInt(255);
blue = random.nextInt(255);
// 用随机产生的颜色将验证码绘制到图像中。
gd.setColor(new Color(red, green, blue));
gd.drawString(sessionCode, xx, codeY);
randomCode.append(sessionCode);
}else {
// 随机产生codeCount数字的验证码。
for (int i = 0; i < codeCount; i++) {
// 得到随机产生的验证码数字。
String code = String.valueOf(codeSequence[random.nextInt(30)]);
// 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。
red = random.nextInt(255);
green = random.nextInt(255);
blue = random.nextInt(255);
// 用随机产生的颜色将验证码绘制到图像中。
gd.setColor(new Color(red, green, blue));
gd.drawString(code, (i + 1) * xx, codeY);
// 将产生的四个随机数组合在一起。
randomCode.append(code);
}
}
//存放验证码
map.put("code", randomCode);
//存放生成的验证码BufferedImage对象
map.put("codePic", buffImg);
return map;
}
}

View File

@@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -59,16 +60,29 @@ public class FileController {
}
@GetMapping("/deleteFile")
public ReturnResponse<Object> deleteFile(String fileName,String password) {
public ReturnResponse<Object> deleteFile(HttpServletRequest request, String fileName, String password) {
ReturnResponse<Object> checkResult = this.deleteFileCheck(fileName);
if (checkResult.isFailure()) {
return checkResult;
}
fileName = checkResult.getContent().toString();
if(!ConfigConstants.getPassword().equalsIgnoreCase(password)) {
if(ConfigConstants.getDeleteCaptcha()){
String sessionCode;
try {
sessionCode = request.getSession().getAttribute("code").toString(); //获取已经保存的验证码
} catch (Exception e) {
sessionCode = "null";
}
if (password==null || !sessionCode.equalsIgnoreCase(password)){
logger.error("删除文件【{}】失败,密码错误!",fileName);
return ReturnResponse.failure("删除文件失败,密码错误!");
}
}else {
if(password==null || !ConfigConstants.getPassword().equalsIgnoreCase(password)) {
logger.error("删除文件【{}】失败,密码错误!",fileName);
return ReturnResponse.failure("删除文件失败,密码错误!");
}
}
File file = new File(fileDir + demoPath + fileName);
logger.info("删除文件:{}", file.getAbsolutePath());
if (file.exists() && !file.delete()) {
@@ -76,6 +90,7 @@ public class FileController {
logger.error(msg);
return ReturnResponse.failure(msg);
}
request.getSession().removeAttribute("code"); //删除缓存验证码
return ReturnResponse.success();
}

View File

@@ -1,5 +1,6 @@
package cn.keking.web.controller;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute;
import cn.keking.service.FileHandlerService;
import cn.keking.service.FilePreview;
@@ -7,6 +8,7 @@ import cn.keking.service.FilePreviewFactory;
import cn.keking.service.cache.CacheService;
import cn.keking.service.impl.OtherFilePreviewImpl;
import cn.keking.utils.KkFileUtils;
import cn.keking.utils.RandomValidateCodeUtil;
import cn.keking.utils.WebUtils;
import fr.opensagres.xdocreport.core.io.IOUtils;
import io.mola.galimatias.GalimatiasParseException;
@@ -15,18 +17,26 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.RenderedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import static cn.keking.service.FilePreview.PICTURE_FILE_PREVIEW_PAGE;
@@ -160,6 +170,82 @@ public class OnlinePreviewController {
}
}
}
/**
* 验证码方法
*/
@RequestMapping("/captcha")
public void captcha(HttpServletRequest request, HttpServletResponse response) throws Exception {
if(!ConfigConstants.getDeleteCaptcha()){
return;
}
response.setContentType("image/gif");
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
Date date = new Date(); // 当前时间
SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 设置时间格式
String sessionCode;
try {
sessionCode = request.getSession().getAttribute("code").toString(); //获取已经保存的验证码
} catch (Exception e) {
sessionCode= null;
}
Object time = request.getSession().getAttribute("time"); //获取已经保存的时间
if (ObjectUtils.isEmpty(time)){ //判断时间是否为空
request.getSession().setAttribute("time", formater.format(date)); //为空重新添加缓存时间
time = request.getSession().getAttribute("time");
}
Date joinTime = formater.parse(String.valueOf(time));
String dateStart = formater.format(joinTime);
Date d1=formater.parse(dateStart);
// 时间差:
long diff = date.getTime() - d1.getTime();
long diffSeconds = diff / 1000 % 60;
String ip=request.getRemoteAddr();
ServletOutputStream sos = null;
if (ObjectUtils.isEmpty(sessionCode) || diffSeconds > 50){ //判断验证码是否为空 为空重新生成 判断是否在有效时间内 默认50秒
Map<String, Object> codeMap = RandomValidateCodeUtil.generateCodeAndPic(ip,sessionCode,0);
// 验证码存入session
request.getSession().setAttribute("code", codeMap.get("code").toString());
// 时间存入session
request.getSession().setAttribute("time", formater.format(date));
// 禁止图像缓存。
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", -1);
response.setContentType("image/jpeg");
// 将图像输出到Servlet输出流中。
try {
sos = response.getOutputStream();
ImageIO.write((RenderedImage) codeMap.get("codePic"), "jpeg", sos);
} catch (IOException e) {
e.printStackTrace();
} finally {
assert sos != null;
sos.close();
}
}else {
// System.out.println("请输入你的姓名:");
Map<String, Object> codeMap = RandomValidateCodeUtil.generateCodeAndPic(ip,sessionCode,1);
// 禁止图像缓存。
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", -1);
response.setContentType("image/jpeg");
// 将图像输出到Servlet输出流中。
try {
sos = response.getOutputStream();
ImageIO.write((RenderedImage) codeMap.get("codePic"), "jpeg", sos);
} catch (IOException e) {
e.printStackTrace();
} finally {
assert sos != null;
sos.close();
}
}
}
/**
* 通过api接口入队

View File

@@ -42,6 +42,7 @@ public class AttributeSetFilter implements Filter {
request.setAttribute("fileUploadDisable", ConfigConstants.getFileUploadDisable());
request.setAttribute("beian", ConfigConstants.getBeian());
request.setAttribute("size", ConfigConstants.maxSize());
request.setAttribute("deleteCaptcha", ConfigConstants.getDeleteCaptcha());
}
/**

View File

@@ -111,6 +111,52 @@
</form>
</div>
</div>
<#if deleteCaptcha >
<#-- 获取删除吗 -->
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">获取删除码(注意:每个验证码只能删除一个文件,验证码有效期为50秒)</h3>
</div>
<div class="panel-body">
<img id="verImg" width="130px" height="48px"/>
<button id="getPic" type="button" class="btn btn-success">获取删除码</button>
</div>
</div>
<script>
window.onload = function(){
var windowUrl = window.URL || window.webkitURL; //处理浏览器兼容性
document.getElementById('getPic').onclick = function(e){
//1、创建ajax对象
var xhr = null;
try{
xhr = new XMLHttpRequest();
}catch(error){
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
//2、调用open
xhr.open("get", "/captcha", true);
xhr.responseType = "blob";
//3、调用send
xhr.send();
//4、等待数据响应
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
//判断本次下载的状态码都是多少
if(xhr.status == 200){
var blob = this.response;
$("#verImg").attr("src",windowUrl.createObjectURL(blob));
//$('#verImg').attr('src', xhr.responseText);
// alert(windowUrl.createObjectURL(blob));
}else{
alert("Error:" + xhr.status);
}
}
}
}
}
</script>
</#if>
<#-- 预览测试 -->
<div class="panel panel-success">
<div class="panel-heading">
@@ -164,7 +210,11 @@
<script>
function deleteFile(fileName,password) {
if(window.confirm('你确定要删除文件吗')){
<#if deleteCaptcha >
password = prompt("请输入获取的验证码:");
<#else>
password = prompt("请输入默认密码:123456");
</#if>
$.ajax({
url: '${baseUrl}deleteFile?fileName=' + fileName +'&password='+password,
success: function (data) {