SpringBoot发送邮箱验证码进行校验

最近在试了试使用验证码注册账号和修改密码,这个难度一般,只要按照对应步骤即可。

(在校验验证码时出现小问题,涉及到Redis暂时存储验证码)

一、在此之前需要获得邮箱授权码(我用的是QQ邮箱的)

1、网页版QQ邮箱右上角点击账号与安全

2、进入安全设置,最下面POP3服务需要先绑定手机号

3、点击前往绑定后弹出该页面,要发送对应的短信进行验证

4、绑定后会给你发一个验证码,输入验证码弹出绑定成功页面

5、接下来点击开启服务

6、还要继续发送验证码,可以扫码,也可以选择其他验证方式(也是发短信)

7、短信完成验证后,点击我已发送,弹出授权码窗口

可以先记住授权码,待会需要使用,使用授权码意义是不需要在第三方等应用上用密码登录,只需使用授权码即可,防止泄露密码。

二、回到SpringBoot工程

1、先导入邮箱对应依赖

        <!--邮箱授权码,我用的是QQ-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

2、配置resources资源文件下的properties文件(我是用的是yml格式)

spring:
  mail:
    host: smtp.qq.com
    username: XXXX@qq.com #用来发邮件的邮箱
    password: XXXX #你的邮箱授权码
    default-encoding: UTF-8

其中host后面跟的是收邮件/发邮件的服务器(收pop3/发smtp),可以自行百度

3、发送验证码接口实现类SendCodeServiceImpl ,前端传来参数邮箱param

import com.xuecheng.checkcode.model.CheckCodeResultDto;
import com.xuecheng.checkcode.service.AbstractCheckCodeService;
import com.xuecheng.checkcode.service.SendCodeService;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import java.io.IOException;


/**
 * @description:
 * @author: xinTong
 * @create: 2024-02-14 12:53
 **/
@Service
public class SendCodeServiceImpl implements SendCodeService {

    @Autowired
    private AbstractCheckCodeService abstractCheckCodeService;

    @Value("${spring.mail.username}")
    private String sendUser;

    @Autowired
    private JavaMailSender javaMailSender;


    public CheckCodeResultDto send(String param) {
        //邮箱验证码
        // 1、先生成验证码
        // 2、存入Redis
        AbstractCheckCodeService.GenerateResult emailCode = abstractCheckCodeService
                .generate(null, 4, "EmailCode", 180);
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();

        simpleMailMessage.setFrom(sendUser);
        simpleMailMessage.setTo(param);
        simpleMailMessage.setSubject("验证码");
        simpleMailMessage.setText("Code:" + emailCode.getCode());

        javaMailSender.send(simpleMailMessage);
        CheckCodeResultDto checkCodeResultDto = new CheckCodeResultDto();
        checkCodeResultDto.setKey(emailCode.getKey());
        return checkCodeResultDto;
    }
}

其中的参数是Form --邮件发送者,Subject--邮件标题,Test--邮件内容,To--邮件收件者

4、存入中间件Redis中

向之前的properties配置类中添加

  redis:
    host: localhost #你的主机
    port: 6379       #端口号
    password: redis #你的redis密码
    database: 0
    lettuce:
      pool:
        max-active: 20
        max-idle: 10
        min-idle: 0
    timeout: 10000

Redis工具类:

import com.xuecheng.checkcode.service.CheckCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * redis存储验证码
 */
@Component("RedisCheckCodeStore")
public class RedisCheckCodeStore implements CheckCodeService.CheckCodeStore {

    @Autowired
    RedisTemplate redisTemplate;


    @Override
    public void set(String key, String value, Integer expire) {
        redisTemplate.opsForValue().set(key,value,expire, TimeUnit.SECONDS);
    }

    @Override
    public String get(String key) {
        return (String) redisTemplate.opsForValue().get(key);
    }

    @Override
    public void remove(String key) {
        redisTemplate.delete(key);
    }
}

 验证码生成工具类:

import com.xuecheng.checkcode.model.CheckCodeParamsDto;
import com.xuecheng.checkcode.model.CheckCodeResultDto;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;


@Slf4j
public abstract class AbstractCheckCodeService implements CheckCodeService {

    protected CheckCodeGenerator checkCodeGenerator;
    protected KeyGenerator keyGenerator;
    protected CheckCodeStore checkCodeStore;

    public abstract void  setCheckCodeGenerator(CheckCodeGenerator checkCodeGenerator);
    public abstract void  setKeyGenerator(KeyGenerator keyGenerator);
    public abstract void  setCheckCodeStore(CheckCodeStore CheckCodeStore);


    /**
     * @description 生成验证公用方法
     * @param checkCodeParamsDto 生成验证码参数
     * @param code_length 验证码长度
     * @param keyPrefix key的前缀
     * @param expire 过期时间
     * @return com.xuecheng.checkcode.service.AbstractCheckCodeService.GenerateResult 生成结果
    */
    public GenerateResult generate(CheckCodeParamsDto checkCodeParamsDto,Integer code_length,String keyPrefix,Integer expire){
        //生成四位验证码
        String code = checkCodeGenerator.generate(code_length);
        log.debug("生成验证码:{}",code);
        //生成一个key
        String key = keyGenerator.generate(keyPrefix);

        //存储验证码
        checkCodeStore.set(key,code,expire);
        //返回验证码生成结果
        GenerateResult generateResult = new GenerateResult();
        generateResult.setKey(key);
        generateResult.setCode(code);
        return generateResult;
    }

    @Data
    public class GenerateResult{
        String key;
        String code;
    }


    public abstract CheckCodeResultDto generate(CheckCodeParamsDto checkCodeParamsDto);


    public boolean verify(String key, String code){
        if (StringUtils.isBlank(key) || StringUtils.isBlank(code)){
            return false;
        }
        String code_l = checkCodeStore.get(key);
        if (code_l == null){
            return false;
        }
        boolean result = code_l.equalsIgnoreCase(code);
        if(result){
            //删除验证码 -- Redis中的
            checkCodeStore.remove(key);
        }
        return result;
    }


}

 5、验证码接口CheckCodeService

import com.xuecheng.checkcode.model.CheckCodeParamsDto;
import com.xuecheng.checkcode.model.CheckCodeResultDto;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.util.Map;


public interface CheckCodeService {


    /**
     * @description 生成验证码
     * @param checkCodeParamsDto 生成验证码参数
     * @return com.xuecheng.checkcode.model.CheckCodeResultDto 验证码结果
    */
     CheckCodeResultDto generate(CheckCodeParamsDto checkCodeParamsDto);

     /**
      * @description 校验验证码
      * @param key
      * @param code
      * @return boolean
     */
    public boolean verify(String key, String code);


    /**
     * @description 验证码生成器
    */
    public interface CheckCodeGenerator{
        /**
         * 验证码生成
         * @return 验证码
         */
        String generate(int length);
        

    }

    /**
     * @description key生成器
     */
    public interface KeyGenerator{

        /**
         * key生成
         * @return 验证码
         */
        String generate(String prefix);
    }


    /**
     * @description 验证码存储
     */
    public interface CheckCodeStore{

        /**
         * @description 向缓存设置key
         * @param key key
         * @param value value
         * @param expire 过期时间,单位秒
         * @return void
        */
        void set(String key, String value, Integer expire);

        String get(String key);

        void remove(String key);
    }
}

可以试试,有问题可以私聊我,有可能会漏一点代码

  • 17
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值