mirror of
https://gitee.com/freshday/radar.git
synced 2025-12-26 07:16:26 +08:00
opts: 优化captcha 机制,取消 session的使用
feihu wang
This commit is contained in:
parent
82c9bd9c1d
commit
2a8b48ed0d
@ -3,24 +3,27 @@ package com.pgmmers.radar.controller;
|
||||
|
||||
import com.alibaba.excel.util.IoUtils;
|
||||
import com.pgmmers.radar.enums.FieldType;
|
||||
import com.pgmmers.radar.service.cache.CacheService;
|
||||
import com.pgmmers.radar.service.common.CommonResult;
|
||||
import com.pgmmers.radar.service.impl.engine.Plugin.PluginManager;
|
||||
import com.pgmmers.radar.util.RandomValidateCode;
|
||||
import com.pgmmers.radar.util.CaptchaUtil;
|
||||
import com.pgmmers.radar.util.ZipUtils;
|
||||
import com.pgmmers.radar.vo.common.PluginVO;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
@ -39,6 +42,10 @@ public class CommonApiController {
|
||||
@Value("${sys.conf.workdir}")
|
||||
public String workDir;
|
||||
|
||||
@Autowired
|
||||
private CacheService cacheService;
|
||||
|
||||
|
||||
@GetMapping("/plugins")
|
||||
public CommonResult plugins() {
|
||||
CommonResult result = new CommonResult();
|
||||
@ -69,18 +76,12 @@ public class CommonApiController {
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/getCaptcha")
|
||||
public void getCaptcha(HttpServletRequest request, HttpServletResponse response) {
|
||||
response.setContentType("image/jpeg");// 设置相应类型,告诉浏览器输出的内容为图片
|
||||
response.setHeader("Pragma", "No-cache");// 设置响应头信息,告诉浏览器不要缓存此内容
|
||||
response.setHeader("Cache-Control", "no-cache");
|
||||
response.setDateHeader("Expire", 0);
|
||||
RandomValidateCode randomValidateCode = new RandomValidateCode();
|
||||
try {
|
||||
randomValidateCode.genRandcode(request, response);//输出图片方法
|
||||
} catch (Exception e) {
|
||||
logger.error("get captcha error", e);
|
||||
}
|
||||
@GetMapping(value = "/getCaptcha", produces = MediaType.IMAGE_JPEG_VALUE)
|
||||
public ResponseEntity getCaptcha() {
|
||||
CaptchaUtil captchaUtil = new CaptchaUtil();
|
||||
CaptchaUtil.Captcha captcha = captchaUtil.genRandcode();
|
||||
cacheService.cacheCaptcha(captcha.getCaptcha().toUpperCase());
|
||||
return ResponseEntity.ok(captcha.getContents());
|
||||
}
|
||||
|
||||
@PostMapping(value = "/upload")
|
||||
|
||||
@ -6,6 +6,7 @@ import com.pgmmers.radar.intercpt.ContextHolder;
|
||||
import com.pgmmers.radar.intercpt.JsonWebTokenService;
|
||||
import com.pgmmers.radar.intercpt.TokenBody;
|
||||
import com.pgmmers.radar.service.admin.UserService;
|
||||
import com.pgmmers.radar.service.cache.CacheService;
|
||||
import com.pgmmers.radar.service.common.CommonResult;
|
||||
import com.pgmmers.radar.util.CryptUtils;
|
||||
import com.pgmmers.radar.vo.admin.UserVO;
|
||||
@ -41,11 +42,14 @@ public class SysLoginApiController {
|
||||
@Autowired
|
||||
private JsonWebTokenService tokenService;
|
||||
|
||||
@Autowired
|
||||
private CacheService cacheService;
|
||||
|
||||
@PostMapping("/merchant/login")
|
||||
public CommonResult login(String loginName, String passwd, String captcha, HttpServletRequest request) {
|
||||
public CommonResult login(String loginName, String passwd, String captcha) {
|
||||
CommonResult ret = new CommonResult();
|
||||
ret.setSuccess(false);
|
||||
String checkResult = checkParam(loginName, passwd, passwd, captcha, request);
|
||||
String checkResult = checkParam(loginName, passwd, passwd, captcha);
|
||||
if(!StringUtils.isEmpty(checkResult)){
|
||||
ret.setMsg(checkResult);
|
||||
return ret;
|
||||
@ -68,8 +72,10 @@ public class SysLoginApiController {
|
||||
}));
|
||||
ret.getData().put("x-auth-token", token);
|
||||
ret.setSuccess(true);
|
||||
} else
|
||||
} else {
|
||||
ret.setMsg("用户名和密码错误!");
|
||||
}
|
||||
|
||||
} else {
|
||||
ret.setMsg("用户名和密码错误!");
|
||||
}
|
||||
@ -88,15 +94,15 @@ public class SysLoginApiController {
|
||||
|
||||
/**
|
||||
* 注册接口
|
||||
* @param request
|
||||
* @param
|
||||
* @return
|
||||
* @author xushuai
|
||||
*/
|
||||
@PostMapping("/merchant/regist")
|
||||
public CommonResult regist(String loginName, String passwd, String verifyPasswd, String captcha,String giteeAccount, HttpServletRequest request) {
|
||||
public CommonResult regist(String loginName, String passwd, String verifyPasswd, String captcha, String giteeAccount) {
|
||||
CommonResult result = new CommonResult();
|
||||
|
||||
String checkResult = checkParam(loginName, passwd, verifyPasswd, captcha, request);
|
||||
String checkResult = checkParam(loginName, passwd, verifyPasswd, captcha);
|
||||
if(!StringUtils.isEmpty(checkResult)){
|
||||
result.setMsg(checkResult);
|
||||
return result;
|
||||
@ -130,7 +136,7 @@ public class SysLoginApiController {
|
||||
return result;
|
||||
}
|
||||
|
||||
private String checkParam(String loginName, String passwd, String verifyPasswd, String captcha, HttpServletRequest request){
|
||||
private String checkParam(String loginName, String passwd, String verifyPasswd, String captcha){
|
||||
if(StringUtils.isEmpty(loginName)){
|
||||
return "登录名称不能为空";
|
||||
}
|
||||
@ -140,9 +146,8 @@ public class SysLoginApiController {
|
||||
if(StringUtils.isEmpty(captcha)){
|
||||
return "验证码不能为空";
|
||||
}
|
||||
String sourceCaptcha = (String) request.getSession(true).getAttribute("captcha");
|
||||
request.getSession().removeAttribute("captcha");
|
||||
if (captcha == null || !captcha.equalsIgnoreCase(sourceCaptcha) ) {
|
||||
boolean validateCaptcha = cacheService.validateCaptcha(captcha);
|
||||
if (!validateCaptcha ) {
|
||||
return "验证码无效";
|
||||
}
|
||||
if(!passwd.equals(verifyPasswd)){
|
||||
|
||||
@ -0,0 +1,163 @@
|
||||
package com.pgmmers.radar.util;
|
||||
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
/**
|
||||
* CaptchaUtil class.
|
||||
*
|
||||
* @author feihu.wang
|
||||
*/
|
||||
public class CaptchaUtil {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(CaptchaUtil.class);
|
||||
private Random random = new Random();
|
||||
private String randString = "23456789ABCDEFGHIJKLMNPQRSTUVWXYZ";
|
||||
private int width = 140;
|
||||
private int height = 30;
|
||||
private int lineSize = 40;
|
||||
private int stringNum = 4;
|
||||
|
||||
/**
|
||||
* 获得字体.
|
||||
*
|
||||
* @return a {@link Font} object.
|
||||
*/
|
||||
private Font getFont() {
|
||||
return new Font("Fixedsys", Font.CENTER_BASELINE, 18);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>获得颜色.</p>
|
||||
*
|
||||
* @param fc a {@link Integer} object.
|
||||
* @param bc a {@link Integer} object.
|
||||
* @return a {@link Color} object.
|
||||
*/
|
||||
private Color getRandColor(int fc, int bc) {
|
||||
if (fc > 255) {
|
||||
fc = 255;
|
||||
}
|
||||
if (bc > 255) {
|
||||
bc = 255;
|
||||
}
|
||||
|
||||
int r = fc + random.nextInt(bc - fc - 16);
|
||||
int g = fc + random.nextInt(bc - fc - 14);
|
||||
int b = fc + random.nextInt(bc - fc - 18);
|
||||
return new Color(r, g, b);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return captcha
|
||||
*/
|
||||
public Captcha genRandcode() {
|
||||
Captcha captcha = new Captcha();
|
||||
// BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
|
||||
Graphics g = image.getGraphics();
|
||||
g.fillRect(0, 0, width, height);
|
||||
g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));
|
||||
g.setColor(getRandColor(110, 133));
|
||||
// 绘制干扰线
|
||||
for (int i = 0; i <= lineSize; i++) {
|
||||
drowLine(g);
|
||||
}
|
||||
// 绘制随机字符
|
||||
String randomString = "";
|
||||
for (int i = 1; i <= stringNum; i++) {
|
||||
randomString = drowString(g, randomString, i);
|
||||
}
|
||||
|
||||
g.dispose();
|
||||
logger.info("curr captcha:{}", randomString);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
try {
|
||||
// 将内存中的图片通过流动形式输出到客户端
|
||||
ImageIO.write(image, "JPEG", out);
|
||||
captcha.setCaptcha(randomString);
|
||||
captcha.setContents(out.toByteArray());
|
||||
} catch (Exception e) {
|
||||
logger.error("create register rand code error" , e);
|
||||
captcha.setCaptcha("");
|
||||
}
|
||||
return captcha;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制字符串.
|
||||
*
|
||||
* @param g a {@link Integer} object.
|
||||
* @param randomString a {@link Integer} object.
|
||||
* @return a {@link Color} object.
|
||||
*/
|
||||
private String drowString(Graphics g, String randomString, int i) {
|
||||
g.setFont(getFont());
|
||||
g.setColor(new Color(random.nextInt(101), random.nextInt(111), random
|
||||
.nextInt(121)));
|
||||
String rand = String.valueOf(getRandomString(random.nextInt(randString
|
||||
.length())));
|
||||
randomString += rand;
|
||||
g.translate(random.nextInt(25), random.nextInt(5));
|
||||
g.drawString(rand, 13 * i, 16);
|
||||
return randomString;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制干扰线.
|
||||
*
|
||||
* @param g a {@link Graphics} object.
|
||||
*/
|
||||
private void drowLine(Graphics g) {
|
||||
int x = random.nextInt(width);
|
||||
int y = random.nextInt(height);
|
||||
int xl = random.nextInt(13);
|
||||
int yl = random.nextInt(15);
|
||||
g.drawLine(x, y, x + xl, y + yl);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取随机的字符.
|
||||
*
|
||||
* @param num a {@link Integer} object.
|
||||
* @return a {@link String} object.
|
||||
*/
|
||||
public String getRandomString(int num) {
|
||||
return String.valueOf(randString.charAt(num));
|
||||
}
|
||||
|
||||
public class Captcha {
|
||||
|
||||
private String captcha;
|
||||
|
||||
private byte[] contents;
|
||||
|
||||
public String getCaptcha() {
|
||||
return captcha;
|
||||
}
|
||||
|
||||
public void setCaptcha(String captcha) {
|
||||
this.captcha = captcha;
|
||||
}
|
||||
|
||||
public byte[] getContents() {
|
||||
return contents;
|
||||
}
|
||||
|
||||
public void setContents(byte[] contents) {
|
||||
this.contents = contents;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ import java.util.Random;
|
||||
*
|
||||
* @author feihu.wang
|
||||
*/
|
||||
@Deprecated
|
||||
public class RandomValidateCode {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(RandomValidateCode.class);
|
||||
|
||||
@ -33,6 +33,8 @@ public class CacheServiceImpl implements CacheService {
|
||||
public static final String PUB_SUB_ACTIVATION_CHANNEL = "radar_channel_activation";
|
||||
public static final String PUB_SUB_LISTRECORD_CHANNEL = "radar_channel_listrecord";
|
||||
public static final String PUB_SUB_DATALIST_CHANNEL = "radar_channel_datalist";
|
||||
public static final String LOGIN_CAPTCHA_PREFIX = "log_captcha_";
|
||||
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
@ -143,4 +145,14 @@ public class CacheServiceImpl implements CacheService {
|
||||
redisService.subscribe(PUB_SUB_DATALIST_CHANNEL, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cacheCaptcha(String captcha) {
|
||||
redisService.setex(LOGIN_CAPTCHA_PREFIX + captcha, captcha, 60);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateCaptcha(String captcha) {
|
||||
return redisService.contains(LOGIN_CAPTCHA_PREFIX + captcha.toUpperCase());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import com.pgmmers.radar.vo.model.ModelVO;
|
||||
import com.pgmmers.radar.vo.model.PreItemVO;
|
||||
import com.pgmmers.radar.vo.model.RuleVO;
|
||||
|
||||
|
||||
public interface CacheService {
|
||||
void saveAntiFraudResult(String modelId, String sessionId, CommonResult result);
|
||||
|
||||
@ -46,4 +47,8 @@ public interface CacheService {
|
||||
void publishDataList(DataListsVO dataList);
|
||||
void subscribeDataList(SubscribeHandle handler);
|
||||
|
||||
|
||||
void cacheCaptcha(String captcha);
|
||||
|
||||
boolean validateCaptcha(String captcha);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user