优化验证码模块相关代码,解决一个可能由于并发导致多发短信,或者多生成验证结果的情景。

This commit is contained in:
Chopper 2021-11-03 09:14:05 +08:00
parent af37386821
commit 956a6e465a
7 changed files with 20 additions and 32 deletions

View File

@ -32,14 +32,8 @@ public class SliderImageController {
@GetMapping("/{verificationEnums}") @GetMapping("/{verificationEnums}")
@ApiOperation(value = "获取校验接口,一分钟同一个ip请求10次") @ApiOperation(value = "获取校验接口,一分钟同一个ip请求10次")
public ResultMessage getSliderImage(@RequestHeader String uuid, @PathVariable VerificationEnums verificationEnums) { public ResultMessage getSliderImage(@RequestHeader String uuid, @PathVariable VerificationEnums verificationEnums) {
try { return ResultUtil.data(verificationService.createVerification(verificationEnums, uuid));
return ResultUtil.data(verificationService.createVerification(verificationEnums, uuid));
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
log.error("获取校验接口错误", e);
throw new ServiceException(ResultCode.VERIFICATION_EXIST);
}
} }
@LimitPoint(name = "slider_image", key = "verification_pre_check", limit = 600) @LimitPoint(name = "slider_image", key = "verification_pre_check", limit = 600)

View File

@ -42,11 +42,8 @@ public class SmsController {
@RequestHeader String uuid, @RequestHeader String uuid,
@PathVariable String mobile, @PathVariable String mobile,
@PathVariable VerificationEnums verificationEnums) { @PathVariable VerificationEnums verificationEnums) {
if (verificationService.check(uuid, verificationEnums)) { verificationService.check(uuid, verificationEnums);
smsUtil.sendSmsCode(mobile, verificationEnums, uuid); smsUtil.sendSmsCode(mobile, verificationEnums, uuid);
return ResultUtil.success(ResultCode.VERIFICATION_SEND_SUCCESS); return ResultUtil.success(ResultCode.VERIFICATION_SEND_SUCCESS);
} else {
throw new ServiceException(ResultCode.VERIFICATION_SMS_EXPIRED_ERROR);
}
} }
} }

View File

@ -89,7 +89,7 @@ public interface Cache<T> {
* *
* @param key 缓存key * @param key 缓存key
*/ */
void remove(Object key); Boolean remove(Object key);
/** /**
* 删除 * 删除

View File

@ -78,9 +78,9 @@ public class RedisCache implements Cache {
} }
@Override @Override
public void remove(Object key) { public Boolean remove(Object key) {
redisTemplate.delete(key); return redisTemplate.delete(key);
} }
/** /**

View File

@ -426,8 +426,8 @@ public enum ResultCode {
*/ */
VERIFICATION_SEND_SUCCESS(80201, "短信验证码,发送成功"), VERIFICATION_SEND_SUCCESS(80201, "短信验证码,发送成功"),
VERIFICATION_ERROR(80202, "验证失败"), VERIFICATION_ERROR(80202, "验证失败"),
VERIFICATION_SMS_ERROR(80203, "短信验证码错误,请重新校验"), VERIFICATION_CODE_INVALID(80204, "验证码已失效,请重新校验"),
VERIFICATION_SMS_EXPIRED_ERROR(80204, "验证码已失效,请重新校验"), VERIFICATION_SMS_CHECKED_ERROR(80210, "短信验证码错误,请重新校验"),
/** /**
* 微信相关异常 * 微信相关异常

View File

@ -20,7 +20,7 @@ public interface VerificationService {
* @return 校验对象 * @return 校验对象
* @throws IOException 校验错误 * @throws IOException 校验错误
*/ */
Map<String, Object> createVerification(VerificationEnums verificationEnums, String uuid) throws IOException; Map<String, Object> createVerification(VerificationEnums verificationEnums, String uuid);
/** /**
* 预校验 * 预校验

View File

@ -51,7 +51,7 @@ public class VerificationServiceImpl implements VerificationService {
* @return 验证码参数 * @return 验证码参数
*/ */
@Override @Override
public Map<String, Object> createVerification(VerificationEnums verificationEnums, String uuid) throws IOException { public Map<String, Object> createVerification(VerificationEnums verificationEnums, String uuid) {
if (uuid == null) { if (uuid == null) {
throw new ServiceException(ResultCode.ILLEGAL_REQUEST_ERROR); throw new ServiceException(ResultCode.ILLEGAL_REQUEST_ERROR);
@ -97,8 +97,7 @@ public class VerificationServiceImpl implements VerificationService {
} catch (ServiceException e) { } catch (ServiceException e) {
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
log.error("创建校验错误", e); throw new ServiceException(ResultCode.ERROR);
return null;
} }
} }
@ -136,16 +135,16 @@ public class VerificationServiceImpl implements VerificationService {
public boolean preCheck(Integer xPos, String uuid, VerificationEnums verificationEnums) { public boolean preCheck(Integer xPos, String uuid, VerificationEnums verificationEnums) {
Integer randomX = (Integer) cache.get(cacheKey(verificationEnums, uuid)); Integer randomX = (Integer) cache.get(cacheKey(verificationEnums, uuid));
if (randomX == null) { if (randomX == null) {
return false; throw new ServiceException(ResultCode.VERIFICATION_CODE_INVALID);
} }
log.debug("{}{}", randomX, xPos); log.debug("{}{}", randomX, xPos);
//验证结果 //验证结果正确 && 删除标记成功
if (Math.abs(randomX - xPos) < verificationCodeProperties.getFaultTolerant()) { if (Math.abs(randomX - xPos) < verificationCodeProperties.getFaultTolerant() && cache.remove(cacheResult(verificationEnums, uuid))) {
//验证成功则记录验证结果 验证有效时间与验证码创建有效时间一致 //验证成功则记录验证结果 验证有效时间与验证码创建有效时间一致
cache.put(cacheResult(verificationEnums, uuid), true, verificationCodeProperties.getEffectiveTime()); cache.put(cacheResult(verificationEnums, uuid), true, verificationCodeProperties.getEffectiveTime());
return true; return true;
} }
return false; throw new ServiceException(ResultCode.VERIFICATION_ERROR);
} }
/** /**
@ -157,13 +156,11 @@ public class VerificationServiceImpl implements VerificationService {
*/ */
@Override @Override
public boolean check(String uuid, VerificationEnums verificationEnums) { public boolean check(String uuid, VerificationEnums verificationEnums) {
Object object = cache.get(cacheResult(verificationEnums, uuid)); //如果有校验标记则返回校验结果
if (object == null) { if (cache.remove(cacheResult(verificationEnums, uuid))) {
return false;
} else {
cache.remove(cacheResult(verificationEnums, uuid));
return true; return true;
} }
throw new ServiceException(ResultCode.VERIFICATION_CODE_INVALID);
} }
/** /**