增加验证码功能

This commit is contained in:
TinyAnts
2023-01-17 18:02:55 +08:00
parent f2038fa7af
commit 84cded01f2
13 changed files with 452 additions and 7 deletions

View File

@@ -13,8 +13,9 @@ public class AdminConfig {
// 免登录验证
public static String[] notLoginUri = new String[]{
"system:login", // 登录接口
"index:config" // 配置接口
"system:captcha", // 验证码
"system:login", // 登录接口
"index:config" // 配置接口
};
// 免权限验证

View File

@@ -0,0 +1,45 @@
package com.mdd.admin.config;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
import static com.google.code.kaptcha.Constants.*;
/**
* 验证码配置
*/
@Configuration
public class KaptChaConfig {
@Bean(name = "captchaProducer")
public DefaultKaptcha getKaptchaBean() {
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
Properties properties = new Properties();
// 是否边框
properties.setProperty(KAPTCHA_BORDER, "yes");
// 字符颜色
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
// 图片宽度
properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
// 图片高度
properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
// 字符大小
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");
// 验证键码
properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
// 字符长度
properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
// 字体样式
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
// 图片样式
properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
Config config = new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}

View File

@@ -2,17 +2,14 @@ package com.mdd.admin.controller.system;
import com.mdd.admin.service.ISystemLoginService;
import com.mdd.admin.validate.system.SystemAdminLoginsValidate;
import com.mdd.admin.vo.system.SystemCaptchaVo;
import com.mdd.admin.vo.system.SystemLoginVo;
import com.mdd.common.core.AjaxResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* 系统登录管理
@@ -24,6 +21,18 @@ public class SystemLoginController {
@Resource
ISystemLoginService iSystemLoginService;
/**
* 验证码
*
* @author fzr
* @return AjaxResult<SystemCaptchaVo>
*/
@GetMapping("/captcha")
public AjaxResult<SystemCaptchaVo> captcha() {
SystemCaptchaVo vo = iSystemLoginService.captcha();
return AjaxResult.success(vo);
}
/**
* 登录系统
*

View File

@@ -1,6 +1,7 @@
package com.mdd.admin.service;
import com.mdd.admin.validate.system.SystemAdminLoginsValidate;
import com.mdd.admin.vo.system.SystemCaptchaVo;
import com.mdd.admin.vo.system.SystemLoginVo;
import java.util.Map;
@@ -10,6 +11,14 @@ import java.util.Map;
*/
public interface ISystemLoginService {
/**
* 验证码
*
* @author fzr
* @return SystemCaptchaVo
*/
SystemCaptchaVo captcha();
/**
* 登录
*

View File

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mdd.admin.service.ISystemAuthAdminService;
import com.mdd.admin.service.ISystemLoginService;
import com.mdd.admin.validate.system.SystemAdminLoginsValidate;
import com.mdd.admin.vo.system.SystemCaptchaVo;
import com.mdd.admin.vo.system.SystemLoginVo;
import com.mdd.common.entity.system.SystemAuthAdmin;
import com.mdd.common.entity.system.SystemLogLogin;
@@ -14,13 +15,19 @@ import com.mdd.common.exception.OperateException;
import com.mdd.common.mapper.system.SystemAuthAdminMapper;
import com.mdd.common.mapper.system.SystemLogLoginMapper;
import com.mdd.common.util.*;
import com.google.code.kaptcha.Producer;
import nl.bitwalker.useragentutils.UserAgent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.FastByteArrayOutputStream;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.*;
/**
@@ -29,6 +36,9 @@ import java.util.*;
@Service
public class SystemLoginServiceImpl implements ISystemLoginService {
@Resource
Producer captchaProducer;
@Resource
SystemLogLoginMapper systemLogLoginMapper;
@@ -41,6 +51,42 @@ public class SystemLoginServiceImpl implements ISystemLoginService {
private static final Logger log = LoggerFactory.getLogger(SystemLoginServiceImpl.class);
/**
* 验证码
*
* @author fzr
* @return SystemCaptchaVo
*/
@Override
public SystemCaptchaVo captcha() {
// 验证码信息
String capStr, code;
BufferedImage image;
String uuid = ToolsUtils.makeUUID();
String ip = IpUtils.getIpAddress().replaceAll("\\.", "");
String verifyKey = YmlUtils.get("like.captcha.token") + ip + ":" + uuid;
long expireTime = Long.parseLong(YmlUtils.get("like.captcha.expire"));
// 生成验证码
capStr = code = captchaProducer.createText();
image = captchaProducer.createImage(capStr);
RedisUtils.set(verifyKey, code.toLowerCase(), expireTime);
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
try {
ImageIO.write(image, "jpg", os);
} catch (IOException e) {
log.error("verifyCode Error:" + e.getMessage());
throw new OperateException(e.getMessage());
}
// 返回验证码
String base64 = "data:image/jpeg;base64,"+ Base64Util.encode(os.toByteArray());
SystemCaptchaVo vo = new SystemCaptchaVo();
vo.setUuid(uuid);
vo.setImg(base64);
return vo;
}
/**
* 登录
*
@@ -53,6 +99,19 @@ public class SystemLoginServiceImpl implements ISystemLoginService {
String username = loginsValidate.getUsername();
String password = loginsValidate.getPassword();
String captchaStatus = YmlUtils.get("like.captcha.status");
if (StringUtils.isNotNull(captchaStatus) && captchaStatus.equals("true")) {
Assert.notNull(loginsValidate.getCode(), "code参数缺失");
Assert.notNull(loginsValidate.getUuid(), "uuid参数缺失");
String ip = IpUtils.getIpAddress().replaceAll("\\.", "");
String captchaKey = YmlUtils.get("like.captcha.token") + ip + ":" + loginsValidate.getUuid();
Object code = RedisUtils.get(captchaKey);
RedisUtils.del(captchaKey);
if (StringUtils.isNull(code) || StringUtils.isEmpty(code.toString()) || !loginsValidate.getCode().equals(code.toString())) {
throw new LoginException(HttpEnum.CAPTCHA_ERROR.getCode(), HttpEnum.CAPTCHA_ERROR.getMsg());
}
}
SystemAuthAdmin sysAdmin = systemAuthAdminMapper.selectOne(new QueryWrapper<SystemAuthAdmin>()
.eq("username", username)
.last("limit 1"));

View File

@@ -22,4 +22,8 @@ public class SystemAdminLoginsValidate implements Serializable {
@Length(min = 6, max = 18, message = "账号或密码错误")
private String password;
private String code;
private String uuid;
}

View File

@@ -0,0 +1,14 @@
package com.mdd.admin.vo.system;
import lombok.Data;
/**
* 验证码
*/
@Data
public class SystemCaptchaVo {
private String uuid;
private String img;
}

View File

@@ -9,6 +9,21 @@
"name": "like.production",
"type": "java.lang.String",
"description": "Description for like.production."
},
{
"name": "like.captcha.status",
"type": "java.lang.String",
"description": "Description for like.captcha.status."
},
{
"name": "like.captcha.expire",
"type": "java.lang.String",
"description": "Description for like.captcha.expire."
},
{
"name": "like.captcha.token",
"type": "java.lang.String",
"description": "Description for like.captcha.token."
}
]
}

View File

@@ -1,6 +1,14 @@
# 项目配置
like:
upload-directory: /www/uploads/likeadmin-java/ # 上传目录
# 验证码配置
captcha:
# 是否开启验证码
status: true
# 验证码有效时长
expire: 120
# 验证码缓存键名
token: "captcha:key:"
# 服务配置
server: