短信验证码/邮箱验证码的发送及防刷校验

一、发送短信验证码及接口防刷

1、前台注册或登录页面调用的后端接口(防刷,并利用openfeign调用另一个服务发短信):

@ResponseBody
    @GetMapping("/sms/sendcode")
    public R sendCodeForSms(@RequestParam("phone") String phone){
        //防刷校验防刷(防止60秒内再次发送验证码)
        String redisCode = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone);
        if(!StringUtils.isEmpty(redisCode)){
            Long l = Long.parseLong(redisCode.split("_")[1]);
            if(System.currentTimeMillis()-l<60000){
                //证明以及发过验证码了,时间小于60秒
                return R.error(BizCodeEnume.SMS_CODE_EXCEPTION.getCode(),BizCodeEnume.SMS_CODE_EXCEPTION.getMsg());
            }
        }
        String code = UUID.randomUUID().toString().substring(0,5) + "_" + System.currentTimeMillis();
        //redis缓存验证码,用于注册校验,以及用于防刷(防止60秒内再次发送验证码)
        redisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone,code,5, TimeUnit.MINUTES);
        thirdPartFeignService.sendCode(phone,code.split("_")[0]);
        return R.ok();
    }

在这里插入图片描述
2、openfeign远程调用发送短信的controller:
在这里插入图片描述
3、上面服务的controller中的SmsComponent:

package com.atguigu.gulimall.thirdparty.component;

import lombok.Data;
import org.apache.http.HttpResponse;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import com.atguigu.gulimall.thirdparty.utils.HttpUtils;
import java.util.HashMap;
import java.util.Map;

/**
 * @author guanghaocheng
 * @version 1.0
 * 翼以尘雾之微补益山海,荧烛末光增辉日月
 * @date 2021/6/30 21:06
 * 发送手机短信的组件
 */

@ConfigurationProperties(prefix = "spring.cloud.alicloud.sms")
@Data
@Component
public class SmsComponent {

    private String host;
    private String path;
    private String method;
    private String appcode;
    private String template_id;
    private String expire_at;

    public void sendSmsCode(String phone,String code){
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        //根据API的要求,定义相对应的Content-Type
        headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        Map<String, String> querys = new HashMap<String, String>();
        Map<String, String> bodys = new HashMap<String, String>();
        bodys.put("content", "code:" + code + ",expire_at:" + expire_at);
        bodys.put("phone_number", phone);
        bodys.put("template_id", template_id);


        try {
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            System.out.println(response.toString());
            //获取response的body
            //System.out.println(EntityUtils.toString(response.getEntity()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

是集成了阿里云的发短信接口,httputils在我之前的文章中有,也可以去阿里云文档给出地址中去查看。

二、邮件验证码及防刷校验

与发短信的其实一样

@ResponseBody
    @GetMapping("/email/sendcode")
    public R sendCodeForEmail(@RequestParam("email") String email){
        String s = redisTemplate.opsForValue().get(AuthServerConstant.MAIL_CODE_CACHE_PREFIX + email);
        if(!StringUtils.isEmpty(s)){
            Long l = Long.parseLong(s.split("_")[1]);
            if(System.currentTimeMillis() - l < 60000){
                return R.error(BizCodeEnume.MAIL_CODE_EXCEPTION.getCode(),BizCodeEnume.MAIL_CODE_EXCEPTION.getMsg());
            }
        }
        String code = UUID.randomUUID().toString().substring(0,5)+"_"+System.currentTimeMillis();
        redisTemplate.opsForValue().set(AuthServerConstant.MAIL_CODE_CACHE_PREFIX + email,code,5,TimeUnit.MINUTES);
        thirdPartFeignService.sendCodeForEmail(email,code.split("_")[0]);
        return R.ok();
    }

远程被调用发邮件的controller:
在这里插入图片描述
service:

/**
     * 邮件发送验证码
     * @param to
     * @param code
     */
    @Override
    public void sendCode(String[] to, String code) throws MessagingException {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);
        helper.setSubject("验证码");//标题
        helper.setText("<b>您的验证码为<span style='color:red;'>"+code+"</span>,有效期" + expire + "分钟</b>",true);//内容,可以用html设置样式,但是必须是true,默认是false
        helper.setFrom("1304058312@qq.com");//发送人
        helper.setTo(to);
        javaMailSender.send(mimeMessage);
    }
实现发送手机短信验证码邮箱验证码的注册登录功能可以分为以下几步: 1. 获取用户输入的手机号或邮箱地址,点击发送验证码按钮后,向后台起请求。 2. 后台接收到请求后,生成随机验证码,并将验证码保存到后台或发送到用户手机或邮箱。 3. 用户输入验证码后,前端将用户输入的验证码和后台保存的验证码进行比对,验证成功后,允许用户完成注册或登录操作。 具体实现方法如下: 1. 发送手机短信验证码 (1)引入阿里云短信SDK,可以使用以下代码发送短信验证码: ```java DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "<accessKeyId>", "<accessSecret>"); IAcsClient client = new DefaultAcsClient(profile); CommonRequest request = new CommonRequest(); request.setMethod(MethodType.POST); request.setDomain("dysmsapi.aliyuncs.com"); request.setVersion("2017-05-25"); request.setAction("SendSms"); request.putQueryParameter("PhoneNumbers", "<手机号>"); request.putQueryParameter("SignName", "<短信签名>"); request.putQueryParameter("TemplateCode", "<短信模板>"); request.putQueryParameter("TemplateParam", "{\"code\":\"" + code + "\"}"); CommonResponse response = client.getCommonResponse(request); String result = response.getData(); ``` 其,<accessKeyId>和<accessSecret>是阿里云账号的AccessKey ID和AccessKey Secret,<手机号>是用户输入的手机号,<短信签名>和<短信模板>需要在阿里云管理控制台进行配置,<code>是生成的短信验证码。 (2)后台保存验证码,可以使用session或Redis等进行保存。 2. 发送邮箱验证码 (1)引入JavaMail API,可以使用以下代码发送邮件验证码: ```java Properties props = new Properties(); props.setProperty("mail.smtp.host", "<SMTP服务器地址>"); props.setProperty("mail.smtp.auth", "true"); props.setProperty("mail.smtp.port", "<SMTP服务器端口>"); props.setProperty("mail.smtp.ssl.enable", "true"); Session session = Session.getDefaultInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("<邮箱地址>", "<邮箱密码>"); } }); String code = generateCode(); // 生成随机验证码 Message message = new MimeMessage(session); message.setFrom(new InternetAddress("<件人邮箱>")); message.setRecipient(Message.RecipientType.TO, new InternetAddress("<收件人邮箱>")); message.setSubject("<邮件主题>"); message.setText("您的验证码是:" + code); Transport.send(message); ``` 其,<SMTP服务器地址>和<SMTP服务器端口>是邮箱服务商提供的SMTP服务器地址和端口号,<邮箱地址>和<邮箱密码>是发送邮件的邮箱地址和密码,<件人邮箱>和<收件人邮箱>是邮件的发送者和接收者,<邮件主题>是邮件的主题,<code>是生成的邮箱验证码。 (2)后台保存验证码,可以使用session或Redis等进行保存。 3. 验证码校验 (1)前端发送验证码后,用户输入验证码,可以使用以下代码进行验证码校验: ```javascript $.ajax({ url: "<后台校验验证码接口>", type: "POST", data: { code: "<用户输入的验证码>" }, success: function (result) { if (result.code === 0) { alert("验证码校验成功"); } else { alert("验证码校验失败"); } } }); ``` (2)后台校验验证码,可以使用以下代码进行验证: ```java String code = request.getParameter("code"); // 获取用户输入的验证码 String sessionCode = (String) request.getSession().getAttribute("<验证码在session的key>"); if (code.equals(sessionCode)) { // 验证码校验成功 } else { // 验证码校验失败 } ``` 其,<验证码在session的key>是验证码在session保存的key值。如果验证码保存在Redis,则需要通过Redis API进行获取。 以上就是实现发送手机短信验证码邮箱验证码的注册登录功能的方法。需要注意的是,发送短信验证码发送邮箱验证码的代码实现方式有所不同,开者需要根据实际情况进行选择。同时,为了保证验证码的安全性,建议对短信验证码邮箱验证码进行有效期限制和刷措施。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值