阿里云验证码

我们在实现登录注册的时候,常常用到了短信验证码校验,下面给分享下代码
首先maven 导入jar包

	<dependency>
		<groupId>com.aliyun</groupId>
		<artifactId>aliyun-java-sdk-core</artifactId>
		<version>3.2.8</version>
	</dependency>
	<dependency>
		<groupId>com.aliyun</groupId>
		<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
		<version>1.1.0</version>
	</dependency>

然后编写代码如下

@Slf4j
@Service
public class AliyunSmsServiceImpl implements ISmsService {
    @Autowired
    private AliyunSmsProperties aliyunSmsProperties;

    @Autowired
    private RedisTemplate<String, String> smsRedisTemplate;

    private Random random = new Random(47);

    @Override
    public Msg send(String mobile) {
        Msg<Object> msg = new Msg<>();
        try {
            // 检测是否发送过验证码
            if (this.smsRedisTemplate.hasKey(aliyunSmsProperties.getKeyPrefix() + mobile)) {
                // 获取验证码有效期
                Long currentExpireTime = this.smsRedisTemplate.boundValueOps(aliyunSmsProperties.getKeyPrefix() + mobile).getExpire();

                // 获取重试间隔
                Integer retryInterval = aliyunSmsProperties.getRetryInterval();

                // 获取有效期
                Integer totalExpireTime = aliyunSmsProperties.getExpireTime();

                if (retryInterval + currentExpireTime > totalExpireTime) {
                    msg.setMsg("请勿频繁获取验证码,重获验证码获取最小间隔" + retryInterval + "秒");
                   return  msg;
                }
            }

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < aliyunSmsProperties.getCodeLength(); i++) {
                sb.append(random.nextInt(9));
            }

            String code = sb.toString();

            //设置超时时间-可自行调整
            System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
            System.setProperty("sun.net.client.defaultReadTimeout", "10000");
            //初始化ascClient需要的几个参数
            //短信API产品名称
            final String product = "Dysmsapi";
            //短信API产品域名
            final String domain = "dysmsapi.aliyuncs.com";
            //替换成你的AK
            //你的accessKeyId,参考本文档步骤2
            final String accessKeyId = aliyunSmsProperties.getAccessKeyId();
            //你的accessKeySecret,参考本文档步骤2
            final String accessKeySecret = aliyunSmsProperties.getAccessKeySecret();
            //初始化ascClient,暂时不支持多region
            IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId,
                    accessKeySecret);
            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
            IAcsClient acsClient = new DefaultAcsClient(profile);
            //组装请求对象
            SendSmsRequest request = new SendSmsRequest();
            //必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为20个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
            request.setPhoneNumbers(mobile);
            //必填:短信签名-可在短信控制台中找到
            request.setSignName(aliyunSmsProperties.getSignName());
            //必填:短信模板-可在短信控制台中找到
            request.setTemplateCode(aliyunSmsProperties.getTemplateCode());
            //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
//            request.setTemplateParam("{\"customer\":\"" + mobile + "\"}");
            request.setTemplateParam("{\"code\":\"" + code + "\"}");
            //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
//            request.setOutId("yourOutId");
            //请求失败这里会抛ClientException异常
            SendSmsResponse response = acsClient.getAcsResponse(request);
            log.debug("发送短信验证码结果:{}", JSON.toJSONString(response));

            if (response.getCode() != null && response.getCode().equals("OK")) {
                //请求成功
                msg.setData(response.getBizId());
                msg.setResult(EnError.DEFAULT);
                log.debug("发送短信验证码成功,手机号码:{},验证码:{}", mobile, code);
                this.smsRedisTemplate.opsForValue().set(aliyunSmsProperties.getKeyPrefix() + mobile, String.valueOf(code), aliyunSmsProperties.getExpireTime(), TimeUnit.SECONDS);
            } else {
                msg.setMsg(response.getMessage());
            }
        } catch (Exception e) {
            log.error("发送短信验证码失败,{}", e.getMessage());
        }
        return msg;
    }

    /**
     * 短信验证码校验
     *
     * @param mobile 手机号码
     * @param code   短信验证码
     * @return 业务消息
     */
    @Override
    public Msg verify(String mobile, String code) {
        log.debug("短信验证码校验:mobile = [{}],code = [{}]", mobile, code);
        Msg<Object> msg = new Msg<>();
        try {
            // 检测是否发送过验证码
            if (!this.smsRedisTemplate.hasKey(aliyunSmsProperties.getKeyPrefix() + mobile)) {
                msg.setMsg("未获取到验证码");
                return msg;
            }

            String tempCode = this.smsRedisTemplate.opsForValue().get(aliyunSmsProperties.getKeyPrefix()+mobile);
            if (!code.equals(tempCode)) {
                msg.setMsg("验证码不匹配");
            } else {
                msg.setResult(EnError.DEFAULT);
            }
        } catch (Exception e) {
            log.error("短信验证码校验失败,mobile = [{}],code = [{}],{}", mobile, code, e.getMessage());
        }
        return msg;
    }
}

阿里云配置

@Component
@ConfigurationProperties(prefix = "sms.aliyun")
public class AliyunSmsProperties {
    /**
     * 验证码前缀
     * 保存着Redis数据库中使用
     */
    private String keyPrefix = "verify-code:";

    /**
     * 重试间隔:单位为秒
     */
    private int retryInterval = 60;

    /**
     * 验证码有效期:单位为秒
     */
    private int expireTime = 300;

    /**
     * 验证码长度
     */
    private int codeLength = 4;

    /**
     * 你的accessKeyId
     */
    private String accessKeyId = "";

    /**
     * 你的accessKeySecret
     */
    private String accessKeySecret = "";

    /**
     * SignName
     */
    private String signName = "";

    /**
     * SignName
     */
    private String templateCode = "";

    public String getKeyPrefix() {
        return keyPrefix;
    }

    public void setKeyPrefix(String keyPrefix) {
        this.keyPrefix = keyPrefix;
    }

    public int getRetryInterval() {
        return retryInterval;
    }

    public void setRetryInterval(int retryInterval) {
        this.retryInterval = retryInterval;
    }

    public int getExpireTime() {
        return expireTime;
    }

    public void setExpireTime(int expireTime) {
        this.expireTime = expireTime;
    }

    public int getCodeLength() {
        return codeLength;
    }

    public void setCodeLength(int codeLength) {
        this.codeLength = codeLength;
    }

    public String getAccessKeyId() {
        return accessKeyId;
    }

    public void setAccessKeyId(String accessKeyId) {
        this.accessKeyId = accessKeyId;
    }

    public String getAccessKeySecret() {
        return accessKeySecret;
    }

    public void setAccessKeySecret(String accessKeySecret) {
        this.accessKeySecret = accessKeySecret;
    }

    public String getSignName() {
        return signName;
    }

    public void setSignName(String signName) {
        this.signName = signName;
    }

    public String getTemplateCode() {
        return templateCode;
    }

    public void setTemplateCode(String templateCode) {
        this.templateCode = templateCode;
    }
}

注意:第一个代码块中的 new Msg()及return msg 这些代码更改成自己的返回信息,验证码是存在redis 内的,如果您本地未使用redis 请忽略这篇文章,或者选择使用redis。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值