Spring Boot 使用 Mail 实现登录邮箱验证

Spring Boot 使用 Mail 实现登录邮箱验证

引言

在现代的 Web 应用中,用户验证是一个至关重要的功能。电子邮件验证可以有效地防止虚假注册,并确保用户提供的是有效的邮箱地址。在这篇文章中,我们将详细介绍如何使用 Spring Boot 实现用户注册时的邮箱验证功能。

前置条件

  1. 基础的 Java 编程知识。
  2. 基础的 Spring Boot 使用经验。
  3. 已安装的 Spring Boot 开发环境(例如 IntelliJ IDEA 或 Eclipse)。

项目设置

创建 Spring Boot 项目

使用 Spring Initializr 创建一个新的 Spring Boot 项目。选择以下依赖:

  • Spring Web
  • Spring Data JPA
  • Spring Boot DevTools
  • Thymeleaf
  • Spring Security
  • Spring Mail

配置数据库

application.properties 文件中配置数据库连接信息。例如,使用 H2 数据库:

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true

配置邮件服务器

application.properties 文件中添加邮件服务器的配置。例如,使用 Gmail SMTP 服务器:

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=your-email@gmail.com
spring.mail.password=your-email-password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

实现步骤

1. 创建用户实体类

创建一个 User 实体类,用于存储用户信息。

package com.example.demo.model;import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;@Entity
public class User {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;private String email;private String password;private boolean enabled;// Getters and Setters
}

2. 创建用户仓库接口

创建一个 UserRepository 接口,用于与数据库交互。

package com.example.demo.repository;import com.example.demo.model.User;
import org.springframework.data.jpa.repository.JpaRepository;public interface UserRepository extends JpaRepository<User, Long> {User findByEmail(String email);
}

3. 创建用户服务类

创建一个 UserService 类,包含用户注册和验证逻辑。

package com.example.demo.service;import com.example.demo.model.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;import java.util.UUID;@Service
public class UserService {@Autowiredprivate UserRepository userRepository;@Autowiredprivate JavaMailSender mailSender;public void registerUser(User user) {user.setEnabled(false);userRepository.save(user);String token = UUID.randomUUID().toString();// Save token to the database (omitted for brevity)sendVerificationEmail(user.getEmail(), token);}private void sendVerificationEmail(String email, String token) {String subject = "Email Verification";String verificationUrl = "http://localhost:8080/verify?token=" + token;String message = "Please click the following link to verify your email: " + verificationUrl;SimpleMailMessage emailMessage = new SimpleMailMessage();emailMessage.setTo(email);emailMessage.setSubject(subject);emailMessage.setText(message);mailSender.send(emailMessage);}
}

4. 创建注册控制器

创建一个 RegistrationController,处理用户注册请求。

package com.example.demo.controller;import com.example.demo.model.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/api")
public class RegistrationController {@Autowiredprivate UserService userService;@PostMapping("/register")public String registerUser(@RequestBody User user) {userService.registerUser(user);return "Registration successful! Please check your email to verify your account.";}@GetMapping("/verify")public String verifyAccount(@RequestParam String token) {// Verification logic (omitted for brevity)return "Account verified successfully!";}
}

5. 配置安全设置

SecurityConfig 中配置 Spring Security,以允许注册和验证请求。

package com.example.demo.config;import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/api/register", "/api/verify").permitAll().anyRequest().authenticated().and().csrf().disable();return http.build();}
}

6. 编写 Thymeleaf 模板

创建一个简单的 Thymeleaf 模板,用于用户注册。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>Register</title>
</head>
<body><h1>Register</h1><form action="#" th:action="@{/api/register}" th:object="${user}" method="post"><div><label for="email">Email:</label><input type="email" id="email" th:field="*{email}" /></div><div><label for="password">Password:</label><input type="password" id="password" th:field="*{password}" /></div><div><button type="submit">Register</button></div></form>
</body>
</html>

结论

通过以上步骤,我们实现了一个简单的用户注册和邮箱验证功能。这只是一个基本的实现,实际项目中可能需要更多的错误处理和安全措施。希望这篇文章对你有所帮助,如果你有任何问题,请随时留言。

参考文献

  1. Spring Boot Reference Documentation
  2. Thymeleaf Documentation
  3. Spring Security Reference

希望这篇文章对你有帮助,如果有任何问题或需要进一步的说明,请随时与我联系。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/36861.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Day.js

Day.js 是什么&#xff1f; Day.js是一个极简的JavaScript库&#xff0c;可以为现代浏览器解析、验证、操作和显示日期和时间。 Day.js中文网 为什么要使用Day.js &#xff1f; 因为Day.js文件只有2KB左右&#xff0c;下载、解析和执行的JavaScript更少&#xff0c;为代码留下更…

作物检测:YOLOv8+SwanLab

1. 项目介绍 基于深度学习的作物检测通过精准管理和数据驱动决策&#xff0c;能够提高作物产量和质量&#xff0c;优化农业资源利用&#xff0c;推动农业自动化进程&#xff0c;从而保障粮食安全。目前&#xff0c;作物检测领域大多针对单类作物进行检测。因此&#xff0c;本项…

SDIO学习(2)--SD卡 2.0协议

本文参考文档&#xff1a; 《SD Specifications Part 1 Physical Layer Simplified Specification Version 2.00》 1 SD卡简介 1.1 SD卡概念 1.2 SD卡外形和接口 Clk&#xff1a;时钟线&#xff0c;由SDIO主机产生 CMD&#xff1a;命令控制线&#xff0c;SDIO主机通过改…

AI技术在现代社会中的广泛应用及其影响

目录 前言&#xff1a; 一、AI技术在医疗领域的应用 二、AI技术在教育领域的应用 三、AI技术在工业领域的应用 四、AI技术在金融领域的应用 五、AI技术在生活领域的应用 前言&#xff1a; 随着科技的不断发展&#xff0c;人工智能&#xff08;AI&#xff09;技术逐渐成为人…

基于C++标准库实现定时器类

基于C标准库实现定时器类 定时器类是多线程编程中经常设计到的工具类 简单的定时器原理其实很简单&#xff08;是不是有点GNU is not unix的味道;&#xff09;&#xff1a; 创建一个新线程在那个线程里等待等待指定时长后做任务 python标准库中就有这么一个定时器类&#xf…

iOS Swift5 视频播放 能播放各种编码格式的视频的第三方库

1.VLC for ios: MobileVLCKit VLC for ios - github 2.IJKPlayer: IJKMediaFramework 基于 FFmpeg IJKPlayer - github

升级!升级!升级!MobPush基础标签推送全新升级,助力开发者精细化运营

“广播推送点击率不高&#xff0c;会员转化差” “新用户拉新后留存不高&#xff0c;次留、3日留存不达标” “用户的复购较低&#xff0c;黏性不高&#xff0c;导致GMV未达预期” 我们总是会听到运营人员关于目标达成过程中遇到这样或者那样的问题。这些问题汇总起来就回到…

vue3 el-table手动选中某一行、设置默认选中某一行

选中某一行用的是el-table的toggleRowSelection方法&#xff0c;用来切换某一行的选中状态 <template><el-table :data"tableData" ref"myTable" selection-change"handleSelectionChange"><el-table-column type"selectio…

STM32 HAL库 外部中断 实现按键控制LED亮灭

目录 1、为什么使用GPIO外部中断控制LED亮灭&#xff1f; 2、NVIC嵌套向量中断控制器 3、EXTI外部中断 4、项目的硬件排线 5、STM32CUBE_MX配置 6、HAL库代码 7、实际效果 1、为什么使用GPIO外部中断控制LED亮灭&#xff1f; 实现LED亮灭控制有很多方式&#xff0c;其中…

公文出错事非小,这些公文写作的常见错误,你中过招吗?

公文是企事业单位、相关部门内外沟通交流的重要工具&#xff0c;不少“笔杆子”经常需要与公文打交道&#xff0c;每天会接触大量的公文。然而在公文撰写的细微之处&#xff0c;稍有不慎&#xff0c;便可能犯下一些常见的错误。这些错误如同蚁穴&#xff0c;虽小却足以破坏公文…

YAML文件格式详解及应用

YAML文件格式详解及应用 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 什么是YAML&#xff1f; YAML&#xff08;YAML Ain’t Markup Language&#xff09;…

stm32cubemx,adc采样的几种方总结,触发获取adc值的方法dma timer trigger中断

stm32cubemx adc采样的几种方总结&#xff0c;触发获取adc值的方法 timer trigger中断 方法1&#xff0c;软件触发方法2&#xff1a;,Timer触发ADC采集通过DMA搬运 触发获取adc值的方法 Regular Conversion launched by software 软件触发 调用函数即可触发ADC转换 Timer X Cap…

悲观锁、乐观锁与分布式锁详解及Redisson应用

目录 1. 悲观锁&#xff08;Pessimistic Lock&#xff09;2. 乐观锁&#xff08;Optimistic Lock&#xff09;3. Redis分布式锁4. Redisson锁 在多线程或多进程环境下&#xff0c;为了保证数据的一致性&#xff0c;锁机制扮演着至关重要的角色。本文将深入探讨悲观锁、乐观锁的…

使用Python进行数据分析

哈喽,大家好,我是木头左! 14.1 Python在数据分析中的优势 Python作为一种简单易学、功能强大的编程语言,已经成为了数据分析领域的首选工具。它的优势主要体现在以下几个方面: 简洁高效:Python语法简洁明了,易于阅读和编写,能够快速实现复杂的数据分析任务。丰富的库支…

Python基于逻辑回归分类模型、决策树分类模型、LightGBM分类模型和XGBoost分类模型实现车辆贷款违约预测项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 随着经济的发展和人民生活水平的提高&#xff0c;汽车消费在居民消费中所占比例逐渐增加&#xff0c;汽…

克服指标管理痛点,实现数据价值最大化

在当下的企业管理中&#xff0c;由于数据量的激增&#xff0c;管理方式逐渐从基于经验转向基于数据。在此过程中&#xff0c;我们能够通过数据探查业务情况、分析数据&#xff0c;从而获取更优的决策支持数据。这通常通过数据报表或分析平台来实现&#xff0c;对于临时性场景&a…

vue2组件内部获取路由前后变化

问题&#xff1a; 在账户列表页面&#xff0c;需要检测路由变化进行拉取用户数据&#xff0c;不在mounted里面写&#xff0c;就是要检测路由变化并且要获取前后路由的路径&#xff0c;进行一些逻辑的判断 解决&#xff1a; export default {data() {return {user: "&qu…

Feign调用异常

TimeLimiter SuperCareAPI#originalWave(String,String) recorded a timeout exception. 解决方案&#xff1a; 针对超时的接口设置响应时间 feign:client:config:default:connect-timeout: 500000000read-timeout: 500000000 resilience4j:timelimiter:instances:SuperCare…

护眼大路灯哪个牌子好用?五款好用的护眼灯分享

护眼大路灯哪个牌子好用&#xff1f;现在的孩子从幼儿园开始就开始学习&#xff0c;面临的用眼压力就很大&#xff0c;但想要孩子视力不受影响&#xff0c;大路灯是得好好安排起来&#xff0c;但动辄大几千的护眼灯真是让我们这些普通家庭的家长望而却步&#xff0c;有没有好用…

ruoyi-cloud部署过程遇到的问题总结

nacos启动失败 1.集群cluster模式改为单机standalone 修改bin/startup.cmd文件 set MODE"cluster" 改为 set MODE"standalone" 2.密钥长度不够“the length of secret key must great than or equal 32 bytes; ” 转到官网查看一些配置&#xff0c;发现…