java发送QQ邮箱验证码实现登录注册、邮箱验证码防刷校验

一:前台功能实现

1.1 页面编写

在这里插入图片描述

<el-form id="emailForm" size="medium">
                        <el-row>
                            <el-col :span="24">
                                <el-form-item class="icon1" label="邮箱:" prop="email">
                                    <el-input placeholder="邮箱" id="email" style="width: 80%;" v-model="emailForm.email" type="text"></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>

                        <el-row>
                            <el-col :span="24">
                                <el-form-item class="icon1" label="验证码:" prop="checkCode">
                                    <el-input type="text" id="checkCode" v-model="emailForm.checkCode" style="width: 45%;" placeholder="验证码"></el-input>
                                    <a @click="sendEmailCode" id="sendEmailCode" >邮箱验证码</a>
                                </el-form-item>
                            </el-col>
                        </el-row>

                    </el-form>

1.2 发送验证码——sendEmailCode

1.2.1 远程调用发送接口

			/**
             * 发送邮箱验证码
             */
            sendEmailCode(){
                /**
                 * 1.给指定邮箱发送验证码
                 * 2.添加验证码倒计时功能
                 */
                //判断有没有正在进行倒计时操作
                if($(this).hasClass("disabled")){
                    //正在倒计时
                } else {
                    //给指定的手机发送验证码
                    let email = this.emailForm.email;
                    $.get("/sendEmail?email=" + email);
                    this.timeoutChangeStyleEmail();
                }
            },

1.2.1 接口防刷校验——60s内只能发送一次

			timeoutChangeStyleEmail(){
                $("#sendEmailCode").attr("class","disabled");
                if( this.num == 0){
                    $("#sendEmailCode").text("发送验证码");
                    this.num = 60;
                    $("#sendEmailCode").attr("class","");
                } else {
                    let str = this.num + "s 后再次发送";
                    $("#sendEmailCode").text(str);
                    setTimeout(() => {
                        this.timeoutChangeStyleEmail();
                    }, 1000);
                }
                this.num--;
            },

在这里插入图片描述

二:获取QQ邮箱授权码

2.1 登录QQ邮箱

https://wx.mail.qq.com/

2.2 开启SMTP权限

主页->设置->账户->管理服务

2.2.1 设置

在这里插入图片描述

2.2.2 账户

在这里插入图片描述

2.2.3 管理服务

在这里插入图片描述

2.2.4 生成授权码

在这里插入图片描述

2.2.5 复制授权码

![在这里插入图片描述](https://img-blog.csdnimg.cn/9d9fc7674c164692a5be79c9b7ee4c9d.png

三:后台功能实现

3.1 编写配置文件

spring:
  mail:
    host: smtp.qq.com   #给QQ邮箱发送邮件
    username: ##你的QQ邮箱
    password: ###你刚才复制的授权码##
    port: 465
    protocol: smtp
    default-encoding: utf-8
    properties:
      mail:
        # 开启 debug,这样方便开发者查看邮件发送日志
        debug: true
        smtp:
          auth: true
          starttls:
            enable: true
            required: true
          ssl:
            enable: true
          socketFactory:
            port: 465
            class: javax.net.ssl.SSLSocketFactory

3.2 发送验证码工具类

package com.sysg.user.utils;

import com.sysg.base.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.Random;

/**
 * 发送邮件验证码
 */
@Component
@Slf4j
public class EmailUtil {

    @Autowired
    private JavaMailSender javaMailSender;

    /**
     * 读取yml文件中username的值并赋值给sendUserEmail
     */
    @Value("${spring.mail.username}")
    private String sendUserEmail;

    /**
     * 发送邮件验证码
     * @param emailReceiver
     * @return
     */
    public String sendSimpleMail(String emailReceiver) {
        // 构建一个邮件对象
        SimpleMailMessage message = new SimpleMailMessage();
        // 设置邮件发送者
        message.setFrom(sendUserEmail);
        // 设置邮件接收者
        message.setTo(emailReceiver);
        // 设置邮件的主题
        message.setSubject("登录验证码");
        // 设置邮件的正文
        Random random = new Random();
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            int r = random.nextInt(10);
            code.append(r);
        }
        String text = "您的验证码为:" + code + ",请勿泄露给他人。";
        message.setText(text);
        // 发送邮件
        try {
            javaMailSender.send(message);
            log.info("邮件发送成功");
            return code.toString();
        } catch (MailException e) {
            e.printStackTrace();
            log.info("邮件发送失败");
            return StringUtils.EMPTY;
        }
    }
}

此时就收到验证码了
在这里插入图片描述

3.3 验证码防刷校验——60s内不允许再次发送

	public R sendEmail(String email) {
        try {
            //1.接口防刷,防止同一个手机号60s内再次发送
            //UserConstant.EMAIL_CODE_CACHE_PREFIX自行去定义
            String redisEmailCode = stringRedisTemplate.opsForValue().get(UserConstant.EMAIL_CODE_CACHE_PREFIX + email);
            if(!StringUtils.isEmpty(redisEmailCode)){
                long redisDate = Long.parseLong(redisEmailCode.split("_")[1]);
                if(System.currentTimeMillis() - redisDate < 60000){
                    //60秒内不可以再发
                    return R.error("获取验证码过于频繁,请您稍后再试");
                }
            }
            String emailCode = emailUtil.sendSimpleMail(email);
            String dateEmailCode = emailCode + "_" + System.currentTimeMillis();
            //2.验证码的再次校验,存储到redis中。key-email,value-code
            //key——"code:15648961564"  value-564986
            //保存到redis里面,并设置10分钟超时时间
            stringRedisTemplate.opsForValue().set(UserConstant.EMAIL_CODE_CACHE_PREFIX + email,dateEmailCode,10, TimeUnit.MINUTES);
            return R.ok("验证码发送成功");
        } catch (NumberFormatException e) {
            e.printStackTrace();
            return R.error("验证码发送失败");
        }
    }

3.4 通过验证码登录

public R emailLogin(EmailLoginVo vo, HttpSession session) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("email",vo.getEmail());
        User user = userDao.selectOne(wrapper);
        if( user == null){
            return R.error(500, "当前邮箱没有注册,请注册后在使用");
        }
        String token = null;
        //1.校验验证码
        String code = vo.getCheckCode();
        String s = stringRedisTemplate.opsForValue().get(UserConstant.EMAIL_CODE_CACHE_PREFIX + vo.getEmail());
        if(!StringUtils.isEmpty(s)){
            if(code.equals(s.split("_")[0])){
                //校验完成以后删除验证码
                stringRedisTemplate.delete(UserConstant.EMAIL_CODE_CACHE_PREFIX + vo.getEmail());
                //验证码校验通过,登录成功
                String username = user.getUsername();
                //生成token
                token = JwtUtil.createToken(username);
                if(token != null){
                    //将数据存储到session对象中
                    session.setAttribute("user",username);
                    return R.ok(200, "登录成功",token);
                }else{
                    return R.error(400, "登录失败");
                }

            } else {
                return R.error("验证码错误");
            }
        } else {
            //验证码不存在的话,就说明过期了
            return R.error("验证码错误");
        }
    }

此时功能就实现了!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

随意石光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值