添加滑块验证码功能

This commit is contained in:
yangjun 2025-05-28 15:34:26 +08:00
parent 46b9d9e98e
commit f066abcff1
8 changed files with 193 additions and 142 deletions

View File

@ -14,4 +14,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
*/
public interface NuBizAdvisoryInfoMapper extends BaseMapper<NuBizAdvisoryInfo> {
NuBizAdvisoryInfo getUserByTel(@Param("mobile") String mobile);
}

View File

@ -2,4 +2,7 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nu.modules.NuBizAdvisoryInfo.mapper.NuBizAdvisoryInfoMapper">
<select id="getUserByTel" resultType="com.nu.modules.NuBizAdvisoryInfo.entity.NuBizAdvisoryInfo">
select * from nu_biz_advisory_info where tel=#{mobile}
</select>
</mapper>

View File

@ -12,4 +12,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
public interface INuBizAdvisoryInfoService extends IService<NuBizAdvisoryInfo> {
NuBizAdvisoryInfo queryWeixinInfo(String openId, String wechatName);
NuBizAdvisoryInfo getUserByTel(String mobile);
}

View File

@ -32,4 +32,9 @@ public class NuBizAdvisoryInfoServiceImpl extends ServiceImpl<NuBizAdvisoryInfoM
}
return nuBizAdvisoryInfo;
}
@Override
public NuBizAdvisoryInfo getUserByTel(String mobile) {
return baseMapper.getUserByTel(mobile);
}
}

View File

@ -95,6 +95,7 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/sys/sms", "anon");//短信验证码
filterChainDefinitionMap.put("/sys/smsCode", "anon");//短信验证码
filterChainDefinitionMap.put("/sys/checkPhoneCode", "anon");//短信验证码
filterChainDefinitionMap.put("/sys/getHkCode", "anon");//滑块验证码
filterChainDefinitionMap.put("/sys/phoneLogin", "anon");//手机登录
filterChainDefinitionMap.put("/sys/user/checkOnlyUser", "anon");//校验用户是否存在
filterChainDefinitionMap.put("/sys/user/register", "anon");//用户注册

View File

@ -36,7 +36,13 @@
<groupId>org.jeecgframework</groupId>
<artifactId>weixin4j</artifactId>
</dependency>
<dependency>
<groupId>com.nursingunit.boot</groupId>
<artifactId>nu-admin-biz</artifactId>
<version>2.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</dependencies>
</project>

View File

@ -5,6 +5,8 @@ import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.nu.modules.NuBizAdvisoryInfo.entity.NuBizAdvisoryInfo;
import com.nu.modules.NuBizAdvisoryInfo.service.INuBizAdvisoryInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
@ -66,6 +68,8 @@ public class LoginController {
private BaseCommonService baseCommonService;
@Autowired
private JeecgBaseConfig jeecgBaseConfig;
@Autowired
private INuBizAdvisoryInfoService nuBizAdvisoryInfoService;
private final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890";
@ -395,143 +399,8 @@ public class LoginController {
}
/**
* 短信验证码
* @return
*/
@PostMapping(value = "/smsCode")
public Result<String> smsCode(@RequestParam(name="mobile",required=true) String mobile,@RequestParam(name="smsmode",required=true) String smsmode,HttpServletRequest request) {
Result<String> result = new Result<String>();
String clientIp = IpUtils.getIpAddr(request);
// //手机号模式 登录模式: "2" 注册模式: "1"
log.info("-------- IP:{}, 手机号:{},获取绑定验证码", clientIp, mobile);
if(oConvertUtils.isEmpty(mobile)){
result.setMessage("手机号不允许为空!");
result.setSuccess(false);
return result;
}
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 漏洞发现新漏洞待处理20220906
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+mobile;
Object object = redisUtil.get(redisKey);
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 漏洞发现新漏洞待处理20220906
if (object != null) {
result.setMessage("验证码10分钟内仍然有效");
result.setSuccess(false);
return result;
}
//-------------------------------------------------------------------------------------
//增加 check防止恶意刷短信接口
if(!DySmsLimit.canSendSms(clientIp)){
log.warn("--------[警告] IP地址:{}, 短信接口请求太多-------", clientIp);
result.setMessage("短信接口请求太多,请稍后再试!");
result.setCode(CommonConstant.PHONE_SMS_FAIL_CODE);
result.setSuccess(false);
return result;
}
//-------------------------------------------------------------------------------------
//随机数
String captcha = RandomUtil.randomNumbers(6);
JSONObject obj = new JSONObject();
obj.put("code", captcha);
try {
boolean b = false;
//注册模板
if (CommonConstant.SMS_TPL_TYPE_1.equals(smsmode)) {
SysUser sysUser = sysUserService.getUserByPhone(mobile);
if(sysUser!=null) {
result.error500(" 手机号已经注册,请直接登录!");
baseCommonService.addLog("手机号已经注册,请直接登录!", CommonConstant.LOG_TYPE_1, null);
return result;
}
b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.REGISTER_TEMPLATE_CODE);
}else {
//登录模式校验用户有效性
SysUser sysUser = sysUserService.getUserByPhone(mobile);
result = sysUserService.checkUserIsEffective(sysUser);
if(!result.isSuccess()) {
String message = result.getMessage();
String userNotExist="该用户不存在,请注册";
if(userNotExist.equals(message)){
result.error500("该用户不存在或未绑定手机号");
}
return result;
}
/**
* smsmode 短信模板方式 0 .登录模板1.注册模板2.忘记密码模板
*/
if (CommonConstant.SMS_TPL_TYPE_0.equals(smsmode)) {
//登录模板
b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.LOGIN_TEMPLATE_CODE);
} else if(CommonConstant.SMS_TPL_TYPE_2.equals(smsmode)) {
//忘记密码模板
b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.FORGET_PASSWORD_TEMPLATE_CODE);
}
}
if (b == false) {
result.setMessage("短信验证码发送失败,请稍后重试");
result.setSuccess(false);
return result;
}
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 漏洞发现新漏洞待处理20220906
//验证码10分钟内有效
redisUtil.set(redisKey, captcha, 600);
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 漏洞发现新漏洞待处理20220906
//update-begin--Author:scott Date:20190812 forissues#391
//result.setResult(captcha);
//update-end--Author:scott Date:20190812 forissues#391
result.setSuccess(true);
} catch (ClientException e) {
e.printStackTrace();
result.error500(" 短信接口未配置,请联系管理员!");
return result;
}
return result;
}
@PostMapping("/checkPhoneCode")
public Result<JSONObject> checkPhoneCode(@RequestParam(name="mobile",required=true) String mobile,@RequestParam(name="smscode",required=true) String smscode, HttpServletRequest request) {
Result<JSONObject> result = new Result<JSONObject>();
String phone = mobile;
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
if(isLoginFailOvertimes(phone)){
return result.error500("该用户登录失败次数过多请于10分钟后再次登录");
}
//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
//校验用户有效性
// SysUser sysUser = sysUserService.getUserByPhone(phone);
// result = sysUserService.checkUserIsEffective(sysUser);
// if(!result.isSuccess()) {
// return result;
// }
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 漏洞发现新漏洞待处理20220906
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+phone;
Object code = redisUtil.get(redisKey);
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 漏洞发现新漏洞待处理20220906
if (!smscode.equals(code)) {
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
addLoginFailOvertimes(phone);
//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
return Result.error("手机验证码错误");
}
//用户信息
// userInfo(sysUser, result, request);
//添加日志
// baseCommonService.addLog("用户名: " + sysUser.getUsername() + ",登录成功!", CommonConstant.LOG_TYPE_1, null);
return result;
}
@ -937,8 +806,6 @@ public class LoginController {
}
return result;
}
/**
* 图形验证码
* @param sysLoginModel
@ -964,4 +831,170 @@ public class LoginController {
return Result.ok();
}
/**
* 短信验证码
* @return
*/
@PostMapping(value = "/smsCode")
public Result<String> smsCode(@RequestParam(name="mobile",required=true) String mobile,@RequestParam(name="smsmode",required=true) String smsmode,@RequestParam(name="hkcode",required=true) String hkcode,HttpServletRequest request) {
Result<String> result = new Result<String>();
String clientIp = IpUtils.getIpAddr(request);
// //手机号模式 登录模式: "2" 注册模式: "1"
log.info("-------- IP:{}, 手机号:{},获取绑定验证码", clientIp, mobile);
if(oConvertUtils.isEmpty(mobile)){
result.setMessage("手机号不允许为空!");
result.setSuccess(false);
return result;
}
String redisHKKey = CommonConstant.PHONE_REDIS_KEY_PRE+"HK"+mobile;
Object hkcoderED = redisUtil.get(redisHKKey);
if(!hkcoderED.equals(hkcode)){
result.setMessage("非法操作,不能获取验证码!");
result.setSuccess(false);
return result;
}else{
}
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 漏洞发现新漏洞待处理20220906
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+mobile;
Object object = redisUtil.get(redisKey);
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 漏洞发现新漏洞待处理20220906
if (object != null) {
result.setMessage("验证码10分钟内仍然有效");
result.setSuccess(false);
return result;
}
//-------------------------------------------------------------------------------------
//增加 check防止恶意刷短信接口
if(!DySmsLimit.canSendSms(clientIp)){
log.warn("--------[警告] IP地址:{}, 短信接口请求太多-------", clientIp);
result.setMessage("短信接口请求太多,请稍后再试!");
result.setCode(CommonConstant.PHONE_SMS_FAIL_CODE);
result.setSuccess(false);
return result;
}
//-------------------------------------------------------------------------------------
//随机数
String captcha = RandomUtil.randomNumbers(6);
JSONObject obj = new JSONObject();
obj.put("code", captcha);
try {
boolean b = false;
//注册模板
if (CommonConstant.SMS_TPL_TYPE_1.equals(smsmode)) {
SysUser sysUser = sysUserService.getUserByPhone(mobile);
if(sysUser!=null) {
result.error500(" 手机号已经注册,请直接登录!");
baseCommonService.addLog("手机号已经注册,请直接登录!", CommonConstant.LOG_TYPE_1, null);
return result;
}
b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.REGISTER_TEMPLATE_CODE);
}else {
//登录模式校验用户有效性
NuBizAdvisoryInfo nuBizAdvisoryInfo = nuBizAdvisoryInfoService.getUserByTel(mobile);
// SysUser sysUser = sysUserService.getUserByPhone(mobile);
// result = sysUserService.checkUserIsEffective(sysUser);
if(nuBizAdvisoryInfo == null) {
result.error500("该用户不存在或未绑定手机号");
return result;
}
/**
* smsmode 短信模板方式 0 .登录模板1.注册模板2.忘记密码模板
*/
if (CommonConstant.SMS_TPL_TYPE_0.equals(smsmode)) {
//登录模板
b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.LOGIN_TEMPLATE_CODE);
} else if(CommonConstant.SMS_TPL_TYPE_2.equals(smsmode)) {
//忘记密码模板
b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.FORGET_PASSWORD_TEMPLATE_CODE);
}
}
if (b == false) {
result.setMessage("短信验证码发送失败,请稍后重试");
result.setSuccess(false);
return result;
}
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 漏洞发现新漏洞待处理20220906
//验证码10分钟内有效
redisUtil.set(redisKey, captcha, 600);
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 漏洞发现新漏洞待处理20220906
//update-begin--Author:scott Date:20190812 forissues#391
//result.setResult(captcha);
//update-end--Author:scott Date:20190812 forissues#391
result.setSuccess(true);
} catch (ClientException e) {
e.printStackTrace();
result.error500(" 短信接口未配置,请联系管理员!");
return result;
}
return result;
}
@PostMapping("/checkPhoneCode")
public Result<JSONObject> checkPhoneCode(@RequestParam(name="mobile",required=true) String mobile,@RequestParam(name="smscode",required=true) String smscode, HttpServletRequest request) {
Result<JSONObject> result = new Result<JSONObject>();
String phone = mobile;
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
if(isLoginFailOvertimes(phone)){
return result.error500("该用户登录失败次数过多请于10分钟后再次登录");
}
//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
//校验用户有效性
// SysUser sysUser = sysUserService.getUserByPhone(phone);
// result = sysUserService.checkUserIsEffective(sysUser);
// if(!result.isSuccess()) {
// return result;
// }
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 漏洞发现新漏洞待处理20220906
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+phone;
Object code = redisUtil.get(redisKey);
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 漏洞发现新漏洞待处理20220906
if (!smscode.equals(code)) {
addLoginFailOvertimes(phone);
return Result.error("手机验证码错误");
}
return result;
}
/**
* 获取滑块code
* @param mobile
* @param request
* @return
*/
@PostMapping("/getHkCode")
public Result<JSONObject> getHkCode(@RequestParam(name="mobile",required=true) String mobile, HttpServletRequest request) {
Result<JSONObject> result = new Result<JSONObject>();
String phone = mobile;
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
if(isLoginFailOvertimes(phone)){
return result.error500("该用户登录失败次数过多请于10分钟后再次登录");
}
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+"HK"+phone;
//随机数
String captcha = RandomUtil.randomNumbers(6);
redisUtil.set(redisKey, captcha, 600);
result.setMessage(captcha);
return result;
}
}

View File

@ -255,14 +255,14 @@ jeecg:
excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/bigscreen/category/**,/bigscreen/visual/**,/bigscreen/map/**,/jmreport/bigscreen2/**
#阿里云oss存储和大鱼短信秘钥配置
oss:
accessKey: ??
secretKey: ??
accessKey: LTAI5tB9WHDf3BZsTcQ64Knc
secretKey: QWwOazCWWZxV7ovqgGGfSCpQcUevUZ
endpoint: oss-cn-beijing.aliyuncs.com
bucketName: jeecgdev
# 短信模板
sms-template:
# 签名
signature:
signature: 吉林省捌零信创科技
# 模板code
templateCode:
# 登录短信、忘记密码模板编码
@ -270,7 +270,7 @@ jeecg:
# 修改密码短信模板编码
SMS_465391221:
# 注册账号短信模板编码
SMS_175430166:
SMS_175430166: SMS_319245237
# 在线预览文件服务器地址配置
file-view-domain: http://fileview.jeecg.com
# minio文件上传