SpringBoot使用邮箱发送验证码实现注册功能

 更新时间:2020年02月12日 14:18:51   作者:ForLevin  
这篇文章主要为大家详细介绍了SpringBoot使用邮箱发送验证码实现注册功能实例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文为大家分享了SpringBoot使用邮箱发送验证码实现注册功能实例,供大家参考,具体内容如下

这里有两种方式:
使用Apache Common包中开源的email组件,通过实例化HtmlEmail()对象,可通过配置外置字典、或yml等配置文件实现灵活配置;

依赖:

<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-email</artifactId>
  <version>1.5</version>
</dependency>

使用SpringBoot Starter email组件;

依赖:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

我这里是采用的第一种方式,简单易懂;

首先需要配置Email的各项参数,其中hostname、host、username、passsword(注意:此处的密码并不是登录的密码,而是邮箱开启smtp服务的令牌);
我这里使用SpringBoot的yml配置文件,可以通过切换不同的环境:local/dev/test/pro/prod等等环境实现灵活配置,该配置为自定义配置;

我此处使用的是本人的163邮箱,在实际开发中需要换为公司的或项目专用邮箱;
(注意:此种方式有缺陷,即为不能从外部进行灵活配置,只能写死配置文件,在实际使用上应该配置为数据字典,可以在外部直接进行灵活配置)

yml:

##Email配置
email:
 host-name: smtp.163.com #服务地址,可以直接在web端登录,找到smtp服务看到,163邮箱默认开放25端口,可暂时不设置
 authentication:
  username: xxx.163.com
  password: xxx #手动的设置令牌
 form:
  mail: xxx@163.com #发送方,必须为你设置的username一致
  name: elog #发送方显示的名称,可以随意设置
 charset: UTF-8 #编码格式,一般设置为UTF-8

util:

package com.hisw.rest.utils;

import com.hisw.common.exception.RRException;
import org.apache.commons.mail.HtmlEmail;
/**
 * @ClassName EmailCodeUtils
 * @Description TODO 邮箱验证码工具类
 * @Author liwenju
 * @Date 2019/5/15 14:20
 * @Version 1.0
 **/
public class EmailCodeUtils {

  /**
   * 生成6位随机验证码
   * @return
   */
  public static String getNumber(){
    String str = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    String code = "";
    for(int i= 0;i<6;i++){
      int index = (int)(Math.random()*str.length());
      code+=str.charAt(index);
    }
    return code;
  }

  /**
   * 发送邮箱验证码
   * @param receiverEmail
   * @param subject
   * @param msg
   */
  public static void sendEmailCode(String EMAIL_HOST_NAME,String EMAIL_FORM_MAIL,
               String EMAIL_FORM_NAME,String EMAIL_AUTHENTICATION_USERNAME,
               String EMAIL_AUTHENTICATION_PASSWORD,String receiverEmail,
               String subject,String msg){
    try{
      HtmlEmail email = new HtmlEmail();
      email.setHostName(EMAIL_HOST_NAME);
      email.setCharset("utf-8");
      email.setFrom(EMAIL_FORM_MAIL,EMAIL_FORM_NAME);
      email.setAuthentication(EMAIL_AUTHENTICATION_USERNAME,EMAIL_AUTHENTICATION_PASSWORD);
      email.addTo(receiverEmail);
      email.setSubject(subject);
      email.setMsg(msg);
      email.send();
    }catch (Exception ex){
      throw new Exception("发送验证码失败,原因:"+ex.getMessage());
    }
  }

}

注意:在静态工具类的方法中,不可直接调用@Value(value="$xxx")来获取yml的配置文件的参数值,否则会获取不到值。故不在该util类中直获取。如下所示:

/**
 * 获取邮箱配置
 */
@Value(value = "${email.host-name}")
public String EMAIL_HOST_NAME;

方法示例:

/**
 * 获取邮箱配置
 */
@Value(value = "${email.host-name}")
public String EMAIL_HOST_NAME;

@Value(value = "${email.authentication.username}")
public String EMAIL_AUTHENTICATION_USERNAME;

@Value(value = "${email.authentication.password}")
public String EMAIL_AUTHENTICATION_PASSWORD;

@Value(value = "${email.charset}")
public String EMAIL_CHARSET;

@Value(value = "${email.form.mail}")
public String EMAIL_FORM_MAIL;

@Value(value = "${email.form.name}")
public String EMAIL_FORM_NAME;

@Autowired
private SysUserDao sysUserDao;

@Autowired
private SysUserTokenDao sysUserTokenDao;

@Autowired
private RedisUtils redisUtils;

private Logger logger = LoggerFactory.getLogger(LoginUserServiceImpl.class);
/**
 * 验证码过期时间60s
 */
private Integer redisExpire = 60 * 1000;

/***
 * 根据邮箱验证用户
 * @param account
 * @return
 */
public SysUserEntity queryByEmail(String account){
  SysUserEntity sysUserEntity = new SysUserEntity();
  sysUserEntity.setEmail(account);
  return sysUserDao.selectOne(sysUserEntity);
}

/**
 * 判断该邮箱是否已存在
 * @param email
 * @return
 */
public Boolean checkEmail(String email){
  //首先判断该用户是否已存在
  if (StringUtils.isNotEmpty(email)){
    EntityWrapper<SysUserEntity> userEntityWrapper = new EntityWrapper<>();
    userEntityWrapper.eq("email",email);
    List<SysUserEntity> sysUserList = sysUserDao.selectList(userEntityWrapper);
    //如果已存在该用户
    return sysUserList.size() <= 0;
  }
  return true;
}

/**
 *发送邮箱验证码
 *
 */
public R sendRegisterEmailCode(String email) {
  try {
    //验证邮箱规则
    if (!RegexUtils.checkEmail(email)){
      throw new RRException("The mailbox does not conform to the specification!");
    }
    if (!checkEmail(email)){
      throw new RRException("This mailbox already exists. Please change the user's email and try again!");
    }
    String emailCode = EmailCodeUtils.getNumber();
    //发送验证码
    EmailCodeUtils.sendEmailCode(EMAIL_HOST_NAME, EMAIL_FORM_MAIL,
        EMAIL_FORM_NAME, EMAIL_AUTHENTICATION_USERNAME,
        EMAIL_AUTHENTICATION_PASSWORD, email, EmailTextTemplate.REGISTER_SUBJECT,
        EmailTextTemplate.REGISTER_CONTENT + emailCode + EmailTextTemplate.CONTENT_SUFFIX);
    logger.info("验证码发送成功:{}", email);
    //发送成功,将该验证码按照规定格式放入redis
    redisUtils.set(RestRedisConstant.REST_ELOG_REGISTER_EMAIL_CODE_KEY + email, emailCode, redisExpire);
    logger.info("Redis存储验证码成功:{}", emailCode);
    return R.ok("The verification code has been sent to your mailbox and is valid for 60 seconds.");
  } catch (Exception ex) {
    return R.error(ex.getMessage());
  }
}


/**
 *验证验证码
 /
 public R checkRegisterEmailCode(String email, String code) {
  try {
    String redisCode = redisUtils.get(RestRedisConstant.REST_ELOG_REGISTER_EMAIL_CODE_KEY+email);
    //判断是否已过期
    if (StringUtils.isEmpty(redisCode)){
      return R.error("The E-mail verification code has expired, please try again.");
    }
    //判断验证码是否正确
    if (!StringUtils.equals(redisCode,code)){
      return R.error("The E-mail verification code is wrong. Please try again.");
    }
    //验证成功,从redis中移除该key&value
    redisUtils.delete(RestRedisConstant.REST_ELOG_REGISTER_EMAIL_CODE_KEY+email);
    return R.ok("The E-mail verification code has been verified.");
  }catch (Exception ex){
    throw new RRException(ex.getMessage());
  }
}

说明:R.error (msg)/ throw new RRExcepion(msg)中,msg应该以enum或常量的方式组织起来;
在发送验证码、校验验证码时,应该有一个工具类,验证一个邮箱在特定的短时间内只能发送或验证几次验证码,超过此限制,应该拒绝处理请求;

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • java蓝桥杯历年真题及答案整理(小结)

    java蓝桥杯历年真题及答案整理(小结)

    这篇文章主要介绍了java蓝桥杯历年真题及答案整理(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • 浅谈Java 对于继承的初级理解

    浅谈Java 对于继承的初级理解

    下面小编就为大家带来一篇浅谈Java 对于继承的初级理解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • java web response提供文件下载功能的实例讲解

    java web response提供文件下载功能的实例讲解

    下面小编就为大家分享一篇java web response提供文件下载功能的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • 简单了解SpringMVC全局异常处理常用方法

    简单了解SpringMVC全局异常处理常用方法

    这篇文章主要介绍了简单了解SpringMVC全局异常处理常用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • iOS多线程介绍

    iOS多线程介绍

    这篇文章主要介绍了iOS多线程的相关知识,涉及到对进程,线程等方面的知识讲解,本文非常具有参考价值,感兴趣的朋友一起学习吧
    2016-05-05
  • java并发编程StampedLock高性能读写锁详解

    java并发编程StampedLock高性能读写锁详解

    这篇文章主要为大家介绍了java并发编程StampedLock高性能读写锁的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • Java自动添加重写的toString方法详解

    Java自动添加重写的toString方法详解

    在本篇文章里小编给大家整理了关于Java自动添加重写的toString方法总结,需要的朋友们学习下。
    2019-07-07
  • spring boot项目使用@JsonFormat失效问题的解决

    spring boot项目使用@JsonFormat失效问题的解决

    这篇文章主要介绍了spring boot项目使用@JsonFormat失效问题的解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • idea如何修改文件的file is read-only问题

    idea如何修改文件的file is read-only问题

    这篇文章主要介绍了idea如何修改文件的file is read-only问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • 在Idea2020.1中使用gitee2020.1.0创建第一个代码库的实现

    在Idea2020.1中使用gitee2020.1.0创建第一个代码库的实现

    这篇文章主要介绍了在Idea2020.1中使用gitee2020.1.0创建第一个代码库的实现,文中通过图文示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07

最新评论