Java实现注册登录与邮箱发送账号验证激活功能
作者:秋名山码民
前言
项目流程图如下:
这里我们通过:
- 163邮箱来实现激活码发送
- qq邮箱来进行接收
学习之前需要掌握的知识
- springboot的基本使用方法
- mysql的使用
- mybatis的简单使用
项目环境搭建
这里我们直接使用 Spring Initializr 初始化 Spring Boot 项目
环境依赖选择:
- lombok简化开发,使用注解,避免写重复性代码
- SpringWeb,实现一个前后端的数据交互(一个登录注册验证,没必要写前后端分离)
- MySQL
- MyBatis
完整的pom文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.6</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.demo</groupId> <artifactId>email-login-register</artifactId> <version>0.0.1-SNAPSHOT</version> <name>email-login-register</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-java8time</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.0</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
application.yml配置
server:
port: 8001spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/email?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: qwer123.
mail:
protocol: smtp # 邮件协议
host: smtp.163.com # 网易邮箱 smtp 服务器地址
port: 25
username: mashengmingming@163.com # 发件人邮箱地址
password: # 授权码
default-encoding: utf-8 # 编码字符集
properties:
mail:
debug: true # 开启 debug 模式以后会完整打印邮件发送过程的日志mybatis:
configuration:
map-underscore-to-camel-case: true # 开启驼峰映射
数据库的搭建
注册,登录页面需要的字段:
基本字段:id,email,password 常用的拓展字段:
activation_time // 激活失效时间
confirm_code // 确认代码
is_vaild // 是否可用 0-不可用 1-可用
salt // 加密盐
gmt_create // 创建时间
gmt_modified // 修改时间
具体的建表语句
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键\r\n', `email` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '邮箱', `password` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '密码', `activation_time` timestamp NULL DEFAULT NULL COMMENT '激活失效时间', `confirm_code` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '确认码', `is_vaild` int NULL DEFAULT NULL COMMENT '是否可用,0不可用,1可用', `salt` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '加密盐', `gmt_create` timestamp NULL DEFAULT NULL COMMENT '创建时间', `gmt_modified` timestamp NULL DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `email`(`email` ASC) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic; INSERT INTO `user` VALUES (8, '986438626@qq.com', '09eff3f9a0817674c4d79c01eb156092', '2022-12-20 17:08:09', '1604765517418205184', 1, 'bn1sqy', '2022-12-19 17:08:09', '2022-12-19 17:08:09'); SET FOREIGN_KEY_CHECKS = 1;
前端页面的搭建
前后端不分离下,我们前端页面一般放到templates下面
登录
<!DOCTYPE html> <html> <head> <!-- Standard Meta --> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"> <!-- Site Properties --> <title>Login Example - Semantic</title> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/reset.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/site.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/container.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/grid.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/header.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/image.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/menu.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/divider.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/segment.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/form.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/input.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/button.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/list.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/message.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/icon.css"> <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/form.js"></script> <script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/transition.js"></script> <style type="text/css"> body { background-color: #DADADA; } body > .grid { height: 100%; } .image { margin-top: -100px; } .column { max-width: 450px; } </style> <script> $(document) .ready(function() { $('.ui.form') .form({ fields: { email: { identifier : 'email', rules: [ { type : 'empty', prompt : 'Please enter your e-mail' }, { type : 'email', prompt : 'Please enter a valid e-mail' } ] }, password: { identifier : 'password', rules: [ { type : 'empty', prompt : 'Please enter your password' }, { type : 'length[6]', prompt : 'Your password must be at least 6 characters' } ] } } }) ; }) ; </script> </head> <body> <div class="ui middle aligned center aligned grid"> <div class="column"> <h2 class="ui teal image header"> <img alt="" src="./img/logo.png" class="image"> <div class="content"> LoginDemo </div> </h2> <form class="ui large form" onsubmit="return false"> <div class="ui stacked segment"> <div class="field"> <div class="ui left icon input"> <i class="user icon"></i> <input type="text" id="email" name="email" placeholder="E-mail address"> </div> </div> <div class="field"> <div class="ui left icon input"> <i class="lock icon"></i> <input type="password" id="password" name="password" placeholder="Password"> </div> </div> <div class="ui fluid large teal submit button" id="login">登录</div> </div> <div class="ui error message"></div> </form> <div class="ui message"> <a href="/registry">注册</a> </div> </div> </div> <script type="application/javascript" charset="UTF-8"> $("#login").on("click",function () { $.ajax({ url:"users/login", type:"POST", data:{ email:$("#email").val(), password:$("#password").val(), }, resultType:"JSON", success:function (result) { alert(result.msg); }, error:function (result) { alert(result.msg); } }) }) </script> </body> </html>
注册
<!DOCTYPE html> <html> <head> <!-- Standard Meta --> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"> <!-- Site Properties --> <title>LoginDemo</title> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/reset.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/site.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/container.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/grid.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/header.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/image.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/menu.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/divider.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/segment.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/form.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/input.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/button.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/list.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/message.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/icon.css"> <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/form.js"></script> <script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/components/transition.js"></script> <style type="text/css"> body { background-color: #DADADA; } body > .grid { height: 100%; } .image { margin-top: -100px; } .column { max-width: 450px; } </style> <script> $(document) .ready(function() { $('.ui.form') .form({ fields: { email: { identifier : 'email', rules: [ { type : 'empty', prompt : 'Please enter your e-mail' }, { type : 'email', prompt : 'Please enter a valid e-mail' } ] }, password: { identifier : 'password', rules: [ { type : 'empty', prompt : 'Please enter your password' }, { type : 'length[6]', prompt : 'Your password must be at least 6 characters' } ] } } }) ; }) ; </script> </head> <body> <div class="ui middle aligned center aligned grid"> <div class="column"> <h2 class="ui teal image header"> <!-- <img alt="" src="./img/logo.png" class="image">--> <div class="content"> LoginDemo </div> </h2> <form class="ui large form" onsubmit="return false"> <div class="ui stacked segment"> <div class="field"> <div class="ui left icon input"> <i class="user icon"></i> <input type="text" id="email" name="email" placeholder="E-mail address"> </div> </div> <div class="field"> <div class="ui left icon input"> <i class="lock icon"></i> <input type="password" id="password" name="password" placeholder="Password"> </div> </div> <div class="field"> <div class="ui left icon input"> <i class="lock icon"></i> <input type="password" name="repassword" placeholder="rePassword"> </div> </div> <div class="ui fluid large teal submit button" id="registry">注册</div> </div> <div class="ui error message"></div> </form> <div class="ui message"> <a href="/login">登录</a> </div> </div> </div> <!--交互方法--> <script type="application/javascript" charset="UTF-8"> $("#registry").on("click",function () { $.ajax({ url:"/users/register", /*请求链接*/ type:"POST", /*请求方法*/ data:{ /*获取表当数据*/ email:$("#email").val(), password:$("#password").val(), }, resultType:"JSON", /*数据格式*/ success:function (result){ alert(result.msg); }, error:function (result) { alert(result.msg); } }) }) </script> </body> </html>
发送邮件格式
<html> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <body> <div> Email 地址验证<br> 欢迎注册LoginDemo,这是一封账号激活邮件,只有激活账号后才能登录网站,点击下方链接即可激活账号!<br> 激活链接有效期为24小时,请在规定时间内激活账号!<br> -----------------------------------------------------------------------------<br> -----------------------------------------------------------------------------<br> <a th:href="@{${activationUrl}}"><span th:text="${activationUrl}"></span></a><br> -----------------------------------------------------------------------------<br> -----------------------------------------------------------------------------<br> 感谢您的访问,祝您生活愉快!<br> </div> </body> </html>
长这个样子:
后端代码
格式
典型的分层模型,
pojo
package com.expamle.emailloginregister.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; import java.time.LocalDateTime; @Data @NoArgsConstructor @AllArgsConstructor public class User implements Serializable { private Integer id; // 主键Id private String email; // 邮箱 private String password; // 密码 md5+盐 /* @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")*/ private LocalDateTime activationTime; // 激活失效时间 private String confirmCode; // 确认代码 private Integer isVaild; // 是否可用 0-不可用 1-可用 private String salt; // 加密盐 /* @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") */ private LocalDateTime gmtCreate; // 创建时间 /* @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") */ private LocalDateTime gmtModified; // 修改时间 }
mapper
主要通过mybatis来写一些与user相关的sql语句
package com.expamle.emailloginregister.mapper; import com.expamle.emailloginregister.pojo.User; import org.apache.ibatis.annotations.*; import java.util.List; @Mapper public interface UserMapper { /** * 注册插入用户信息 * */ @Insert("insert into user(email,password,activation_time,confirm_code,is_vaild,salt,gmt_create,gmt_modified)" + "values(#{email},#{password},#{activationTime},#{confirmCode},#{isVaild},#{salt},#{gmtCreate},#{gmtModified})") int insertUser(User user); /** * 根据confirm_code查询与用户是否已激活 * confirm_code * is_vaild * */ @Select("select email,activation_time from user where confirm_code = #{confirmCode} and is_vaild = 0") User findUserByConfirmCode(@Param("confirmCode") String confirmCode); /** * 根据激活码查询用户 并 修改状态值 * */ @Update("update user set is_vaild=1 where confirm_code = #{confirmCode}") int confirmUser(@Param("confirmCode") String confirmCode); /** * 根据邮箱查询账号 * */ @Select("select email,password,salt from user where email=#{email} and is_vaild=1") List<User> findUserByEmail(@Param("email") String email); /** * 用户查重 * */ @Select("select count(*) from user where email=#{email} limit 1") int emailExist(@Param("email") String email); }
Controller
与前端页面进行交互,负责一个登录,注册数据的提交和响应
SystemController
package com.expamle.emailloginregister.controller; import com.expamle.emailloginregister.pojo.User; import com.expamle.emailloginregister.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; /** *@Controller 不可使用RestControoler *使用RestController要进行一个封装 */ @Controller public class SystemController { @Autowired private UserService userService; /** * 登录 * */ @GetMapping("/login") public String login(){ return "login"; } /** * 注册 * */ @GetMapping("/registry") public String registry(User user){ return "registry"; } }
UserController
package com.expamle.emailloginregister.controller; import com.expamle.emailloginregister.pojo.User; import com.expamle.emailloginregister.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.Map; @RestController @RequestMapping("users") public class UserController { @Autowired private UserService userService; /** * 注册账号 * */ @PostMapping("register") public Map<String,Object> registery(User user){ Map<String,Object> map = userService.createAccount(user); return map; } /** * 用户登录 * */ @PostMapping("login") public Map<String,Object> login(User user){ Map<String,Object> map = userService.accountLogin(user); return map; } /** * 账号激活 * 激活码附在请求后 * * */ @GetMapping("activation") public Map<String,Object> activationAccount(String confirmCode){ Map<String,Object> map = userService.activationAccount(confirmCode); return map; } }
service
先写俩个接口,在Impl中进行实现,
EmailServiceImpl
package com.expamle.emailloginregister.service; public interface EmailService { void sendEmail(String email,String activationUrl); }
实现sendEmail
package com.expamle.emailloginregister.service.Impl; import com.expamle.emailloginregister.service.EmailService; import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import javax.annotation.Resource; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; import java.util.Date; /** * 发送邮件相关业务 * */ @Service public class EmailServiceImpl implements EmailService { // 引入配置文件属性 @Value("${spring.mail.username}") private String sendUsername; // javamain mail依赖方法---此方法无法使用autowird注入,javaMailSender不是springboot的方法 @Resource private JavaMailSender javaMailSender; @Resource //同上 private TemplateEngine templateEngine; public void sendEmail(String email,String activationUrl){ // 创建邮件对象 MimeMessage mimeMessage = javaMailSender.createMimeMessage(); try { /** * MineMessagehelper---设置邮件相关内容 * @Params1 邮件对象 * @Params2 是否发送多封邮件 * */ MimeMessageHelper message = new MimeMessageHelper(mimeMessage,true); // 设置邮件主题 message.setSubject("注册账号激活"); // 设置邮件发送者 message.setFrom(sendUsername); // 设置邮件接收者,可多个 message.setTo(email); // 设置邮件抄送人 /* message.setCc();*/ // 设置邮件隐秘抄送人,可多个 /*message.setBcc();*/ // 设置邮件发送日期 message.setSentDate(new Date()); // 创建上下文环境--thym依赖提供方法,使用当前本地前端 Context context = new Context(); // 邮件中传递的链接 context.setVariable("activationUrl",activationUrl); // 映射html文件 String text = templateEngine.process("activation-account.html",context); // 设置邮件正文-true-是否是html模板 message.setText(text,true); } catch (MessagingException e) { e.printStackTrace(); } // 发送邮件 javaMailSender.send(mimeMessage); } }
UserService
package com.expamle.emailloginregister.service; import com.expamle.emailloginregister.pojo.User; import org.springframework.transaction.annotation.Transactional; import java.util.Map; @Transactional public interface UserService { Map<String,Object> createAccount(User user); Map<String, Object> accountLogin(User user); Map<String, Object> activationAccount(String confirmCode); }
具体实现
package com.expamle.emailloginregister.service.Impl; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.RandomUtil; import cn.hutool.crypto.SecureUtil; import com.expamle.emailloginregister.mapper.UserMapper; import com.expamle.emailloginregister.pojo.User; import com.expamle.emailloginregister.service.EmailService; import com.expamle.emailloginregister.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.util.HashMap; import java.util.List; import java.util.Map; @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Autowired private EmailService emailService; /** * 用户注册 * */ @Override public Map<String,Object> createAccount(User user) { // 统一返回对象 Map<String,Object> result = new HashMap<>(); /** * 注册--构建User对象内的数据 * 前端返回参数 email、password * */ // 判断邮箱是否已经存在 int emailExist = userMapper.emailExist(user.getEmail()); if (emailExist == 1){ result.put("code",400); result.put("msg","用户已存在"); return result; } //开始构建user数据 // 激活码--hutool工具生成雪花算法 String confirmCode = IdUtil.getSnowflake(1,1).nextIdStr(); user.setConfirmCode(confirmCode); // 加密密码 password+盐+md5 String password = user.getPassword(); String salt = RandomUtil.randomString(6); // hutool随机生成6个字符 String md5Pwd = SecureUtil.md5(password+salt); // 设置user参数、salt、password user.setSalt(salt); user.setPassword(md5Pwd); // 是否已激活 默认-0 未激活 user.setIsVaild(0); // 激活码有效期 LocalDateTime activationTime = LocalDateTime.now().plusDays(1); // 当前时间增加1天时间 user.setActivationTime(activationTime); // 创建时间 LocalDateTime nowTime = LocalDateTime.now(); user.setGmtCreate(nowTime); user.setGmtModified(nowTime); // 用户信息插入数据库 int insertUser = userMapper.insertUser(user); // 判断数据库写入是否成功并返回相关信息 if (insertUser > 0){ // 准备激活链接 String activationUrl ="http://localhost:8001/users/activation?confirmCode="+confirmCode; //发送邮箱信息 emailService.sendEmail(user.getEmail(), activationUrl); result.put("code",200); result.put("msg","注册成功,请前往邮箱激活账号"); return result; }else{ result.put("code",400); result.put("msg","注册失败"); return result; } } public static void main(String[] args) { String a = SecureUtil.md5("123456"+"qldp40"); System.out.println(a); } /** * 用户登录 * */ @Override public Map<String, Object> accountLogin(User user) { // 统一返回数据 Map<String,Object> result = new HashMap<>(); // 前端数据校验 if (user.getEmail() == null || user.getEmail().isEmpty() || user.getPassword() == null || user.getPassword().isEmpty() ){ result.put("code",400); result.put("msg","请输入账号和密码"); return result; } // 查询用户是否在数据库中 List<User> users = userMapper.findUserByEmail(user.getEmail()); // 判断用户是否异常 if (users == null || users.isEmpty()){ result.put("code",400); result.put("msg","账号未注册或未激活"); return result; } // 查询出多个账号 if (users.size()>1){ result.put("code",400); result.put("msg","账号异常请联系管理员"); return result; } // 得到唯一用户-判断账号是否激活 User DbUser = users.get(0); // 校验密码-获取加密数据 String salt = DbUser.getSalt(); String md5Pwd = SecureUtil.md5(user.getPassword()+salt); /** * DbUser.getPassword().equals(md5Pwd)---可以匹配 * md5Pwd.equals(DbUser.getPassword())---无法匹配 ?????? * */ if (DbUser.getPassword().equals(md5Pwd)){ result.put("code",200); result.put("msg","登录成功"); return result; }else { result.put("code",400); result.put("msg","账号或密码有误"); return result; } } /** * 激活账号 * */ @Override public Map<String, Object> activationAccount(String confirmCode) { // 统一返回参数 Map<String, Object> map = new HashMap<>(); // 通过confirmCount查询用户 User user = userMapper.findUserByConfirmCode(confirmCode); System.out.println(user.toString()); if (user == null ){ map.put("code",400); map.put("msg","账号未注册"); return map; } // 判断激活码有效期 // 当前时间是否在激活码截止期之后 boolean after = LocalDateTime.now().isAfter(user.getActivationTime()); if (after){ map.put("code",400); map.put("msg","链接已失效,请重新获取激活码"); return map; } // 激活账号,修改状态为 1 int confirmUser = userMapper.confirmUser(confirmCode); if (confirmUser == 1){ map.put("code",200); map.put("msg","激活账号成功"); return map; }else{ map.put("code",400); map.put("msg","激活账号失败"); return map; } } }
最后
码云完整代码及部署教程:
https://gitee.com/Vamye/LoginDemo
参考b站视频教程
到此这篇关于Java实现注册登录与邮箱发送账号验证激活功能的文章就介绍到这了,更多相关Java注册登录内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!