第一步。前端调用发送短信验证码的接口

  @Autowiredprivate ResetPasswordService resetPasswordService;@GetMapping("/validate-code")public Result validateCode(@RequestParam String phone) {return resetPasswordService.validateCode(phone);}

第二步,生成验证码并发送(自主生成验证码),反馈给前端

 @Autowiredprivate IIdentifyingCodeService identifyingCodeService;public static final String USER_REGISTER_PASSWORD = "register_password";//要发送的短信内容private String templateOfRegisterStoreSms = "【***-**】%s(****验证码)。工作人员不会向您索要,请勿向任何人泄露,以免造成账户或资金损失。";//验证码的生成范围private int startInclusive = 1000;private int endInclusive = 9999;//验证码有效期private int expire = 60 * 1000;@Overridepublic String validateCode(String phone) {//生成验证码int code = RandomUtils.nextInt(startInclusive, endInclusive);String tokenId= identifyingCodeService.sendCode(phone, USER_REGISTER_PASSWORD, templateOfRegisterStoreSms,String.valueOf(code), expire);return tokenId;}

第三步,发送验证码的service和impl


/*** identifying code service* @author author * @date 2020年2月14日*/
public interface IIdentifyingCodeService {/*** 发送认证码* @param target 目标,一般为手机号* @param type 类型,该类型由具体的使用者自定义即可,只要确保在本方法使用中的type一致即可,该字段作为tokenId的一部分* @param template 消息模板,的定义,默认使用 %s 来格式化字符串,即模板中包含的 %s 将被 参数 code 替换* @param code 认证码,请自主生成* @param expire 超时时间,该认证码失效的时间,单位为秒* @return tokenId 认证码与本tokenId一一对应*/String sendCode(String target, String type, String template, String code, int expire);/*** 获取tokenId对应的code* @param type 参考上述定义* @param tokenId* @return code*/String getCode(String type, String tokenId);/*** 清空tokenId对应的code* @param type 参考上述定义* @param tokenId }方法返回的tokenId* @return code*/void clean(String type, String tokenId);
}

/*** identifying code service impl* @author author * @date 2020年2月14日*/
@Service
@Slf4j
public class IIdentifyingCodeServiceImpl implements IIdentifyingCodeService {public static final String PREFIX_SMS = "SMS";public static final String PREFIX_IDENTIFYING = "IDENTIFYING";public static final String IDENTIFYING_TYPE_OF_POLICY = "policy";private  String separator = ":";private  int keyLength = 10;private  int policyTime = 60 * 1000;@Autowiredprivate RedisUtils redisUtils;@Overridepublic String sendCode(String target, String type, String template, String code, int expire) {Result result = timePolicy(target, policyTime);if(result.getCode().equals(ResultEnum.OPRATOR_FAIL.getCode())){return result;}//阿里发送短信验证码AliSMSClient.sendSMS(target,code);String tokenId = generatorTokenId();redisUtils.setValue(generatorKey(type, tokenId), code, expire);return tokenId;}protected String generatorKey(String type, String tokenId) {String key = new StringBuffer().append(PREFIX_SMS).append(separator).append(PREFIX_IDENTIFYING).append(separator).append(type).append(separator).append(tokenId).toString();return key;}protected String generatorTokenId() {return RandomStringUtils.randomAlphabetic(keyLength);}protected Result timePolicy(String target, int ttl) {Object  oTarget= redisUtils.getValue(generatorKey(IDENTIFYING_TYPE_OF_POLICY, target));if (Objects.nonNull(oTarget)) {log.debug("identifying code time policy: target [{}] is failed. ttl=[{}]", target, ttl);return RespUtil.error(ResultEnum.OPRATOR_FAIL.getCode(),ttl / 1000 + "秒内不能再次发送短信");} else {redisUtils.setValue(generatorKey(IDENTIFYING_TYPE_OF_POLICY, target), target, ttl);return  RespUtil.success(ResultEnum.OPRATOR_SUCCESS.getCode());}}@Overridepublic String getCode(String type, String tokenId) {Object obj = redisUtils.getValue(generatorKey(type, tokenId));if(Objects.isNull(obj)){return "";}return (String)obj;}@Overridepublic void clean(String type, String tokenId) {redisUtils.setValue(generatorKey(type, tokenId), null);}
}

第四步,ali发送短信的接口

/*** 静态常量类* @author author **/
public class Constants {/** 阿里  短信发送访问域名 */public static final String endpoint = "dysmsapi.aliyuncs.com";/** 阿里  AccessKey ID */public static final String accessKeyId = "accessKeyId ";/** 阿里  AccessKey Secret */public static final String accessKeySecret = "accessKeySecret ";/** 阿里  signName */public static final String signName = "signName";/** 阿里  templateCode */public static final String templateCode = "templateCode ";}
/*** * @author author **/
public class AliSMSClient {private static Logger logger = LoggerFactory.getLogger(AliSMSClient.class);private AliSMSClient(){}public static void main(String[] args) {sendSMS("18700000000", "3456");}/*** 使用AK&SK初始化账号Client* @return Client* @throws Exception*/public static Client createClient() throws Exception {Config config = new Config()// 您的AccessKey ID.setAccessKeyId(Constants.accessKeyId)// 您的AccessKey Secret.setAccessKeySecret(Constants.accessKeySecret)// 访问的域名.setEndpoint(Constants.endpoint);return new Client(config);}/*** 发送短信* @param phone* @param SignName  短信签名名称* @param TemplateCode 短信模板ID* @return* @throws Exception*/public static String sendSMS(String phone,String templateParam) {if(StringUtils.isBlank(phone)) {throw new IllegalArgumentException("手机号不能为空");}Client client = null;String ret = "";try {client = createClient();SendSmsRequest sendSmsRequest = new SendSmsRequest().setPhoneNumbers(phone).setSignName(Constants.signName).setTemplateCode(Constants.templateCode).setTemplateParam("{'code':'" + templateParam + "'}");SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);if (null != sendSmsResponse && !"".equals(sendSmsResponse)) {ret = parseResponse(sendSmsResponse);}} catch (Exception e) {e.printStackTrace();throw new CustomException("发送短信失败!");}return ret;}/*** 解析下发response* @param sendSmsResponse* @return*/public static String parseResponse(SendSmsResponse sendSmsResponse) {//"Message":"OK", 状态码的描述。//"RequestId":"2184201F-BFB3-446B-B1F2-C746B7BF0657", 请求ID。//"BizId":"197703245997295588^0", 发送回执ID,可根据该ID在接口QuerySendDetails中查询具体的发送状态。//"Code":"OK" 请求状态码,返回OK代表请求成功。SendSmsResponseBody body = sendSmsResponse.getBody();if("OK".equals(body.getCode())){return "0";}else {return "-1";}}
}

pom文件

     <dependency><groupId>com.aliyun</groupId><artifactId>dysmsapi20170525</artifactId><version>2.0.1</version></dependency>

下面是验证码校验

     @PostMapping("/reset/password")public Result resetPassword(@RequestBody ResetPasswordDTO dto) {return resetPasswordService.resetPassword(dto);}
 @Override@Transactional(rollbackFor = Exception.class)public Result resetPassword(ResetPasswordDTO dto) {Optional<String> oToken = Optional.ofNullable(identifyingCodeService.getCode(USER_REGISTER_PASSWORD,dto.getTokenId()));if (oToken.isPresent()) {if (oToken.get().equals(dto.getCode())) {//验证成功,进行操作//清除验证码identifyingCodeService.clean(USER_REGISTER_PASSWORD, dto.getTokenId());return  RespUtil.success();} else {return RespUtil.error(ResultEnum.OPRATOR_FAIL.getCode(),"短信验证码错误.");}} else {return RespUtil.error(ResultEnum.OPRATOR_FAIL.getCode(),"短信验证码错误.");}}
/*** @author author * @since 2020-09-01*/
@Data
public class ResetPasswordDTO implements Serializable {/*** 验证码*/private String code;/*** 验证码id*/private String tokenId;}

aliyun阿里云发送短信验证码和校验相关推荐

  1. 使用阿里云发送短信验证码

    目录 一.用户注册登录流程 二.使用阿里云发送短信验证码 ⭐生成密钥 ⭐将密钥配置到项目中 ⚪新建properties文件并填入相应信息 ⚪pom配置 ​⚪ 测试代码 ⚪添加签名 ​⚪添加短信发送的模 ...

  2. 使用阿里云发送短信验证码(JAVA实现)

    文章目录 准备工作 完成阿里云认证 生成秘钥 申请签名和模板 编写代码 需要引入的JAR包依赖 代码 充钱 准备工作 我们首先登陆阿里云 https://www.aliyun.com 完成阿里云认证 ...

  3. 新版阿里云发送短信验证码详解

    关与作者更多博客请访问云里云外开源社区 一.申请短信服务步骤 首先进入阿里云控制台,点击左侧产品与服务,找到短信服务. 第一次进入会有新手引导,这里主要介绍一下大致步骤和易错点 申请短信签名和模板 短 ...

  4. 调用阿里云发送短信验证码的工具类

    /*** @Description 阿里云短信发送工具类* @Author 曰业而安*/ public class SendSmsUtil { //phone 手机号 //param 验证码 注意这里 ...

  5. 阿里云发送短信验证码失败

    报错: 把require_once  '/api_sdk/vendor/autoload.php'; 改为 require_once  __DIR__ .'/api_sdk/vendor/autolo ...

  6. 【Springboot】| 阿里云发送短信验证码,你会了吗?

  7. java 阿里云 发送短信功能实现

    1. 注册短信平台(以阿里云为例) 常用短信服务平台:阿里云.华为云.腾讯云.京东.梦网.乐信等 2. 注册成功后,开通短信服务 3. 设置短信签名.短信模板.AccessKey AccessKey ...

  8. Java阿里云发送短信

    文章目录 前言 准备工作 短信服务API介绍 阿里云api发送短信 传送门 前言 短信服务,是阿里云为客户提供的一种通信服务的能力. 准备工作 需要申请一个阿里云账号 开通短信服务 添加签名和模板(需 ...

  9. 【阿里云短信服务SMS】使用阿里云发送短信

    使用阿里云发送短信 前期准备工作 1.添加签名 2.添加短信模板 3.创建子用户,得到密钥:AccessKeyId和 AccessKeySecret 4.给子用户添加权限 5.收集好之前步骤中的4个关 ...

  10. 腾讯云发送短信验证码服务

    腾讯云发送短信验证码服务 1.注册腾讯云的账号 在腾讯云的官网:https://cloud.tencent.com/注册一个腾讯云的账号,就是日常的注册流程(这里就不贴图了),不过要实名认证啥的,认证 ...

最新文章

  1. 带AI无人车上云驾校,不出门练遍各大城市道路,华南理工大学团队拿下“互联网+”大赛金奖...
  2. 谁才是最受欢迎的视频会议软件?就一分钟,求投票
  3. Linkis源码目录结构详解
  4. 实战—用户价值模型搭建
  5. python怎么输出表格中随机数_python 输出一个随机数
  6. SPI、I2C、UART 三种串行总线对比介绍
  7. Jetson AGX Xavier配置cuDNN流程
  8. Antd 多层Modal+Form组件嵌套 如何在父级组件中清空子级组件状态与数据?
  9. 肉袒牵羊的拼音及解释
  10. @sql 单元测试_如何在SQL单元测试中使用假表?
  11. C导出接口与C++导出接口对比
  12. android double值排序,android根据Double类型数据经纬度算出距离再根据距离实现排序功能...
  13. leetCode----day01---- 从排序数组中删除重复项
  14. flash位图技术研究篇(3):移动缓冲区域
  15. 『提醒自己』-自身遗忘掉的知识1
  16. 异步promise、Async/await介绍
  17. php access 所有表,Oracle|sql server|access 数据库里的所有表名,字段名
  18. 【实习之T100开发】帆软报表笔记,Java经典入门教程
  19. 从事游戏开发怎么入门
  20. 服务器自动打印,小技巧! —让打印机自动承担打印任务

热门文章

  1. python-QQ群扫码登录(QQ群验证)
  2. 中国大学MOOC-人工智能实践:Tensorflow笔记-课程笔记 Chapter5
  3. 超大日志文件分割方法
  4. 不是所有数学命题都是可以被证明或证伪
  5. C1任务01-植物大战僵尸修改游戏存档(小白也能看懂)
  6. Ios常用第三方动画框架(三)
  7. DDD之一年级小学生作业辅导
  8. btrfs 入门使用
  9. pgadmin 4 v4.28 keeps loading
  10. Error creating bean with name ‘user‘ defined in file //Pointcut is not well-formed: expecting