SpringBoot中怎么使用邮箱发送验证码实现注册功能
创始人
2024-12-20 11:41:49
0次

依赖:

 org.apache.commons  commons-email  1.5

使用SpringBoot Starter email组件;

依赖:

 org.springframework.boot  spring-boot-starter-mail

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

首先需要配置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;@Autowiredprivate SysUserDao sysUserDao;@Autowiredprivate SysUserTokenDao sysUserTokenDao;@Autowiredprivate 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 userEntityWrapper = new EntityWrapper<>();    userEntityWrapper.eq("email",email);    List 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或常量的方式组织起来;在发送验证码、校验验证码时,应该有一个工具类,验证一个邮箱在特定的短时间内只能发送或验证几次验证码,超过此限制,应该拒绝处理请求;

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...