Springboot实现邮箱验证码注册与修改密码及登录功能详解流程
1. 准备工作
1.1 导入依赖
在 pom.xml
文件中导入以下依赖:
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- JDBC驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 邮箱发送 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
1.2 配置文件
在 application.yml
文件中配置数据库、邮箱、安全等相关信息。
2. 实现激活码注册功能
2.1 用户实体类设计
在 com.example.entity
包下创建 User
实体类:
@Entity
@Table(name = "t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@NotBlank(message = "用户名不能为空")
private String username;
@NotBlank(message = "密码不能为空")
private String password;
@Email(message = "邮箱格式不正确")
private String email;
@NotNull(message = "激活状态不能为空")
private Boolean activated = false;
// getter、setter 省略
}
2.2 用户注册页面设计
在 resources/templates
目录下创建 register.html
页面(使用 Thymeleaf 模板引擎):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>注册</title>
</head>
<body>
<h1>注册</h1>
<form method="post" action="/register">
<label for="email">邮箱:</label>
<input type="email" name="email" id="email" required />
<br/>
<label for="username">用户名:</label>
<input type="text" name="username" id="username" required />
<br/>
<label for="password">密码:</label>
<input type="password" name="password" id="password" required />
<br/>
<input type="submit" value="注册" />
</form>
</body>
</html>
2.3 注册控制器设计
在 com.example.controller
包下创建 UserController
控制器:
@Controller
public class UserController {
@Autowired
private UserService userService;
@Autowired
private MailSenderService mailSenderService;
@GetMapping("/register")
public String register() {
return "register";
}
@PostMapping("/register")
public String register(@Valid User user, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "register";
}
// 判断邮箱是否已注册
if (userService.findByEmail(user.getEmail()) != null) {
bindingResult.rejectValue("email", null, "该邮箱已注册");
return "register";
}
// 生成随机激活码
String activationCode = RandomStringUtils.randomAlphabetic(10);
// 保存用户到数据库
user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));
user.setActivated(false);
user = userService.save(user);
// 发送邮件
mailSenderService.sendActivationMail(user.getEmail(), activationCode);
return "redirect:/activate?email=" + user.getEmail();
}
@GetMapping("/activate")
public String activate(String email, String activationCode, Model model) {
User user = userService.findByEmail(email);
if (user == null) {
model.addAttribute("errorMsg", "用户不存在");
} else if (user.getActivated()) {
model.addAttribute("errorMsg", "用户已激活");
} else if (StringUtils.equals(activationCode, user.getActivationCode())) {
user.setActivated(true);
userService.save(user);
model.addAttribute("successMsg", "激活成功");
} else {
model.addAttribute("errorMsg", "激活码不正确");
}
return "activate";
}
}
2.4 邮件发送服务设计
在 com.example.service
包下创建 MailSenderService
邮件发送服务:
@Service
public class MailSenderService {
@Autowired
private JavaMailSender mailSender;
public void sendActivationMail(String email, String activationCode) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("your@mail.com"); // 发件人邮箱
message.setTo(email); // 收件人邮箱
message.setSubject("激活账号"); // 邮件主题
message.setText("请点击链接进行激活:http://localhost:8080/activate?email=" + email + "&activationCode=" + activationCode); // 邮件内容
mailSender.send(message);
}
}
3. 实现修改密码功能
3.1 修改密码页面设计
在 resources/templates
目录下创建 reset_password.html
页面:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>修改密码</title>
</head>
<body>
<h1>修改密码</h1>
<form method="post" action="/reset_password">
<input type="hidden" name="token" value="[[$token]]" />
<label for="password">新密码:</label>
<input type="password" name="password" id="password" required />
<br/>
<input type="submit" value="修改密码" />
</form>
</body>
</html>
3.2 修改密码控制器设计
在 com.example.controller
包下创建 PasswordResetController
控制器:
@Controller
public class PasswordResetController {
@Autowired
private PasswordResetTokenService tokenService;
@Autowired
private UserService userService;
@GetMapping("/forgot_password")
public String forgotPassword() {
return "forgot_password";
}
@PostMapping("/forgot_password")
public String forgotPassword(String email, Model model) {
User user = userService.findByEmail(email);
if (user == null) {
model.addAttribute("errorMsg", "用户不存在");
} else {
tokenService.createToken(user);
model.addAttribute("successMsg", "已发送邮件,请查收");
}
return "forgot_password";
}
@GetMapping("/reset_password_token")
public String resetPasswordToken(String token, Model model) {
PasswordResetToken resetToken = tokenService.findByToken(token);
if (resetToken == null) {
model.addAttribute("errorMsg", "重置密码链接已失效");
return "reset_password_result";
}
if (resetToken.isExpired()) {
model.addAttribute("errorMsg", "重置密码链接已过期");
return "reset_password_result";
}
model.addAttribute("token", token);
return "reset_password";
}
@PostMapping("/reset_password")
public String resetPassword(String token, String password, Model model) {
PasswordResetToken resetToken = tokenService.findByToken(token);
if (resetToken == null) {
model.addAttribute("errorMsg", "重置密码链接已失效");
return "reset_password_result";
}
if (resetToken.isExpired()) {
model.addAttribute("errorMsg", "重置密码链接已过期");
return "reset_password_result";
}
User user = resetToken.getUser();
user.setPassword(new BCryptPasswordEncoder().encode(password));
userService.save(user);
model.addAttribute("successMsg", "修改密码成功");
return "reset_password_result";
}
}
3.3 重置密码实体类设计
在 com.example.entity
包下创建 PasswordResetToken
实体类:
@Entity
@Table(name = "t_password_reset_token")
public class PasswordResetToken {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@ManyToOne
@JoinColumn(name = "user_id", nullable = false)
private User user;
@Column(unique = true)
private String token;
@NotNull
private Date expiryDate;
// getter、setter 省略
}
3.4 重置密码服务设计
在 com.example.service
包下创建 PasswordResetTokenService
重置密码服务:
@Service
public class PasswordResetTokenService {
@Autowired
private PasswordResetTokenRepository tokenRepository;
public PasswordResetToken createToken(User user) {
PasswordResetToken token = new PasswordResetToken();
token.setUser(user);
token.setToken(UUID.randomUUID().toString());
token.setExpiryDate(new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000)); // 设置为 24 小时后过期
return tokenRepository.save(token);
}
public PasswordResetToken findByToken(String token) {
return tokenRepository.findByToken(token);
}
}
4. 实现登录功能
4.1 登录控制器设计
在 com.example.controller
包下创建 SecurityController
控制器:
@Controller
public class SecurityController {
@GetMapping("/login")
public String login() {
return "login";
}
@GetMapping("/")
public String index() {
return "index";
}
}
4.2 安全配置类设计
在 com.example.config
包下创建 SecurityConfig
安全配置类:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/register", "/activate/**", "/forgot_password", "/reset_password_token/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.defaultSuccessUrl("/")
.and()
.logout()
.permitAll();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
5. 示例说明
5.1 注册账号
- 访问注册页面:http://localhost:8080/register
- 输入邮箱、用户名和密码,点击注册按钮
- 到注册邮箱收取激活邮件,并点击邮件里的激活链接
- 成功激活后,页面跳转到主页
5.2 忘记密码
- 访问忘记密码页面:http://localhost:8080/forgot_password
- 输入邮箱,点击发送重置密码邮件
- 到注册邮箱收取重置密码邮件,并点击邮件里的重置密码链接
- 进入重置密码页面,输入新密码并保存
- 成功修改密码后,页面跳转到重置密码结果页面
5.3 登录
- 访问登录页面:http://localhost:8080/login
- 输入已注册的用户的账号密码,点击登录按钮
- 成功登录后,页面跳转到主页
结语
本文详细讲解了如何使用 Spring Boot 实现邮箱验证码注册与修改密码及登录功能,主要包括用户实体类设计、邮箱发送、注册控制器设计、重置密码实体类设计、重置密码服务设计、登录控制器设计以及安全配置类设计。通过本文的学习,可以快速掌握这些功能的实现流程,有助于提高开发效率。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Springboot实现邮箱验证码注册与修改密码及登录功能详解流程 - Python技术站