Java實(shí)現(xiàn)注冊(cè)登錄與郵箱發(fā)送賬號(hào)驗(yàn)證激活功能
前言
項(xiàng)目流程圖如下:

這里我們通過:
- 163郵箱來實(shí)現(xiàn)激活碼發(fā)送
- qq郵箱來進(jìn)行接收
學(xué)習(xí)之前需要掌握的知識(shí)
- springboot的基本使用方法
- mysql的使用
- mybatis的簡單使用
項(xiàng)目環(huán)境搭建
這里我們直接使用 Spring Initializr 初始化 Spring Boot 項(xiàng)目

環(huán)境依賴選擇:
- lombok簡化開發(fā),使用注解,避免寫重復(fù)性代碼
- SpringWeb,實(shí)現(xiàn)一個(gè)前后端的數(shù)據(jù)交互(一個(gè)登錄注冊(cè)驗(yàn)證,沒必要寫前后端分離)
- 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 # 郵件協(xié)議
host: smtp.163.com # 網(wǎng)易郵箱 smtp 服務(wù)器地址
port: 25
username: mashengmingming@163.com # 發(fā)件人郵箱地址
password: # 授權(quán)碼
default-encoding: utf-8 # 編碼字符集
properties:
mail:
debug: true # 開啟 debug 模式以后會(huì)完整打印郵件發(fā)送過程的日志mybatis:
configuration:
map-underscore-to-camel-case: true # 開啟駝峰映射
數(shù)據(jù)庫的搭建
注冊(cè),登錄頁面需要的字段:
基本字段:id,email,password 常用的拓展字段:
activation_time // 激活失效時(shí)間
confirm_code // 確認(rèn)代碼
is_vaild // 是否可用 0-不可用 1-可用
salt // 加密鹽
gmt_create // 創(chuàng)建時(shí)間
gmt_modified // 修改時(shí)間
具體的建表語句
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 '激活失效時(shí)間', `confirm_code` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '確認(rèn)碼', `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 '創(chuàng)建時(shí)間', `gmt_modified` timestamp NULL DEFAULT NULL COMMENT '更新時(shí)間', 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" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/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">注冊(cè)</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>注冊(cè)
<!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" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/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">注冊(cè)</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", /*請(qǐng)求鏈接*/
type:"POST", /*請(qǐng)求方法*/
data:{ /*獲取表當(dāng)數(shù)據(jù)*/
email:$("#email").val(),
password:$("#password").val(),
},
resultType:"JSON", /*數(shù)據(jù)格式*/
success:function (result){
alert(result.msg);
},
error:function (result) {
alert(result.msg);
}
})
})
</script>
</body>
</html>發(fā)送郵件格式
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<body>
<div>
Email 地址驗(yàn)證<br>
歡迎注冊(cè)LoginDemo,這是一封賬號(hào)激活郵件,只有激活賬號(hào)后才能登錄網(wǎng)站,點(diǎn)擊下方鏈接即可激活賬號(hào)!<br>
激活鏈接有效期為24小時(shí),請(qǐng)?jiān)谝?guī)定時(shí)間內(nèi)激活賬號(hào)!<br>
-----------------------------------------------------------------------------<br>
-----------------------------------------------------------------------------<br>
<a th:href="@{${activationUrl}}"><span th:text="${activationUrl}"></span></a><br>
-----------------------------------------------------------------------------<br>
-----------------------------------------------------------------------------<br>
感謝您的訪問,祝您生活愉快!<br>
</div>
</body>
</html>長這個(gè)樣子:

后端代碼
格式

典型的分層模型,
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; // 激活失效時(shí)間
private String confirmCode; // 確認(rèn)代碼
private Integer isVaild; // 是否可用 0-不可用 1-可用
private String salt; // 加密鹽
/*
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
*/
private LocalDateTime gmtCreate; // 創(chuàng)建時(shí)間
/*
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
*/
private LocalDateTime gmtModified; // 修改時(shí)間
}mapper
主要通過mybatis來寫一些與user相關(guān)的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 {
/**
* 注冊(cè)插入用戶信息
* */
@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);
/**
* 根據(jù)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);
/**
* 根據(jù)激活碼查詢用戶 并 修改狀態(tài)值
* */
@Update("update user set is_vaild=1 where confirm_code = #{confirmCode}")
int confirmUser(@Param("confirmCode") String confirmCode);
/**
* 根據(jù)郵箱查詢賬號(hào)
* */
@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
與前端頁面進(jìn)行交互,負(fù)責(zé)一個(gè)登錄,注冊(cè)數(shù)據(jù)的提交和響應(yīng)
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要進(jìn)行一個(gè)封裝
*/
@Controller
public class SystemController {
@Autowired
private UserService userService;
/**
* 登錄
* */
@GetMapping("/login")
public String login(){
return "login";
}
/**
* 注冊(cè)
* */
@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;
/**
* 注冊(cè)賬號(hào)
* */
@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;
}
/**
* 賬號(hào)激活
* 激活碼附在請(qǐng)求后
*
* */
@GetMapping("activation")
public Map<String,Object> activationAccount(String confirmCode){
Map<String,Object> map = userService.activationAccount(confirmCode);
return map;
}
}service

先寫倆個(gè)接口,在Impl中進(jìn)行實(shí)現(xiàn),
EmailServiceImpl
package com.expamle.emailloginregister.service;
public interface EmailService {
void sendEmail(String email,String activationUrl);
}實(shí)現(xiàn)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;
/**
* 發(fā)送郵件相關(guān)業(yè)務(wù)
* */
@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){
// 創(chuàng)建郵件對(duì)象
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
try {
/**
* MineMessagehelper---設(shè)置郵件相關(guān)內(nèi)容
* @Params1 郵件對(duì)象
* @Params2 是否發(fā)送多封郵件
* */
MimeMessageHelper message = new MimeMessageHelper(mimeMessage,true);
// 設(shè)置郵件主題
message.setSubject("注冊(cè)賬號(hào)激活");
// 設(shè)置郵件發(fā)送者
message.setFrom(sendUsername);
// 設(shè)置郵件接收者,可多個(gè)
message.setTo(email);
// 設(shè)置郵件抄送人
/* message.setCc();*/
// 設(shè)置郵件隱秘抄送人,可多個(gè)
/*message.setBcc();*/
// 設(shè)置郵件發(fā)送日期
message.setSentDate(new Date());
// 創(chuàng)建上下文環(huán)境--thym依賴提供方法,使用當(dāng)前本地前端
Context context = new Context();
// 郵件中傳遞的鏈接
context.setVariable("activationUrl",activationUrl);
// 映射html文件
String text = templateEngine.process("activation-account.html",context);
// 設(shè)置郵件正文-true-是否是html模板
message.setText(text,true);
} catch (MessagingException e) {
e.printStackTrace();
}
// 發(fā)送郵件
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);
}具體實(shí)現(xiàn)
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;
/**
* 用戶注冊(cè)
* */
@Override
public Map<String,Object> createAccount(User user) {
// 統(tǒng)一返回對(duì)象
Map<String,Object> result = new HashMap<>();
/**
* 注冊(cè)--構(gòu)建User對(duì)象內(nèi)的數(shù)據(jù)
* 前端返回參數(shù) email、password
* */
// 判斷郵箱是否已經(jīng)存在
int emailExist = userMapper.emailExist(user.getEmail());
if (emailExist == 1){
result.put("code",400);
result.put("msg","用戶已存在");
return result;
}
//開始構(gòu)建user數(shù)據(jù)
// 激活碼--hutool工具生成雪花算法
String confirmCode = IdUtil.getSnowflake(1,1).nextIdStr();
user.setConfirmCode(confirmCode);
// 加密密碼 password+鹽+md5
String password = user.getPassword();
String salt = RandomUtil.randomString(6); // hutool隨機(jī)生成6個(gè)字符
String md5Pwd = SecureUtil.md5(password+salt);
// 設(shè)置user參數(shù)、salt、password
user.setSalt(salt);
user.setPassword(md5Pwd);
// 是否已激活 默認(rèn)-0 未激活
user.setIsVaild(0);
// 激活碼有效期
LocalDateTime activationTime = LocalDateTime.now().plusDays(1); // 當(dāng)前時(shí)間增加1天時(shí)間
user.setActivationTime(activationTime);
// 創(chuàng)建時(shí)間
LocalDateTime nowTime = LocalDateTime.now();
user.setGmtCreate(nowTime);
user.setGmtModified(nowTime);
// 用戶信息插入數(shù)據(jù)庫
int insertUser = userMapper.insertUser(user);
// 判斷數(shù)據(jù)庫寫入是否成功并返回相關(guān)信息
if (insertUser > 0){
// 準(zhǔn)備激活鏈接
String activationUrl ="http://localhost:8001/users/activation?confirmCode="+confirmCode;
//發(fā)送郵箱信息
emailService.sendEmail(user.getEmail(), activationUrl);
result.put("code",200);
result.put("msg","注冊(cè)成功,請(qǐng)前往郵箱激活賬號(hào)");
return result;
}else{
result.put("code",400);
result.put("msg","注冊(cè)失敗");
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) {
// 統(tǒng)一返回?cái)?shù)據(jù)
Map<String,Object> result = new HashMap<>();
// 前端數(shù)據(jù)校驗(yàn)
if (user.getEmail() == null || user.getEmail().isEmpty() ||
user.getPassword() == null || user.getPassword().isEmpty()
){
result.put("code",400);
result.put("msg","請(qǐng)輸入賬號(hào)和密碼");
return result;
}
// 查詢用戶是否在數(shù)據(jù)庫中
List<User> users = userMapper.findUserByEmail(user.getEmail());
// 判斷用戶是否異常
if (users == null || users.isEmpty()){
result.put("code",400);
result.put("msg","賬號(hào)未注冊(cè)或未激活");
return result;
}
// 查詢出多個(gè)賬號(hào)
if (users.size()>1){
result.put("code",400);
result.put("msg","賬號(hào)異常請(qǐng)聯(lián)系管理員");
return result;
}
// 得到唯一用戶-判斷賬號(hào)是否激活
User DbUser = users.get(0);
// 校驗(yàn)密碼-獲取加密數(shù)據(jù)
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","賬號(hào)或密碼有誤");
return result;
}
}
/**
* 激活賬號(hào)
* */
@Override
public Map<String, Object> activationAccount(String confirmCode) {
// 統(tǒng)一返回參數(shù)
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","賬號(hào)未注冊(cè)");
return map;
}
// 判斷激活碼有效期
// 當(dāng)前時(shí)間是否在激活碼截止期之后
boolean after = LocalDateTime.now().isAfter(user.getActivationTime());
if (after){
map.put("code",400);
map.put("msg","鏈接已失效,請(qǐng)重新獲取激活碼");
return map;
}
// 激活賬號(hào),修改狀態(tài)為 1
int confirmUser = userMapper.confirmUser(confirmCode);
if (confirmUser == 1){
map.put("code",200);
map.put("msg","激活賬號(hào)成功");
return map;
}else{
map.put("code",400);
map.put("msg","激活賬號(hào)失敗");
return map;
}
}
}最后
碼云完整代碼及部署教程:
https://gitee.com/Vamye/LoginDemo
參考b站視頻教程
到此這篇關(guān)于Java實(shí)現(xiàn)注冊(cè)登錄與郵箱發(fā)送賬號(hào)驗(yàn)證激活功能的文章就介紹到這了,更多相關(guān)Java注冊(cè)登錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 5分鐘教你使用java搞定網(wǎng)站登錄驗(yàn)證碼
- Java?自定義注解在登錄驗(yàn)證的應(yīng)用示例
- Java登錄功能實(shí)現(xiàn)token生成與驗(yàn)證
- 教你用Java驗(yàn)證服務(wù)器登錄系統(tǒng)
- Java Web制作登錄驗(yàn)證碼實(shí)現(xiàn)代碼解析
- JavaWeb簡單用戶登錄注冊(cè)實(shí)例代碼(有驗(yàn)證碼)
- Java Web實(shí)現(xiàn)登錄頁面驗(yàn)證碼驗(yàn)證功能
- java圖片滑動(dòng)驗(yàn)證(登錄驗(yàn)證)原理與實(shí)現(xiàn)方法詳解
- java實(shí)現(xiàn)登錄驗(yàn)證碼
- Java基于Session登錄驗(yàn)證的實(shí)現(xiàn)示例
相關(guān)文章
Java同步鎖Synchronized底層源碼和原理剖析(推薦)
這篇文章主要介紹了Java同步鎖Synchronized底層源碼和原理剖析,釋放后,進(jìn)入減減操作、直到為0然后喚醒隊(duì)列,讓他們?nèi)帄Z鎖,循環(huán)前面步驟,對(duì)Java同步鎖Synchronized相關(guān)知識(shí)感興趣的朋友一起看看吧2022-05-05
SpringBoot Event 事件如何實(shí)現(xiàn)異步延遲執(zhí)行
這篇文章主要介紹了Spring Boot Event 事件如何實(shí)現(xiàn)異步延遲執(zhí)行問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
Java利用文件輸入輸出流實(shí)現(xiàn)文件夾內(nèi)所有文件拷貝到另一個(gè)文件夾
這篇文章主要介紹了Java實(shí)現(xiàn)文件夾內(nèi)所有文件拷貝到另一個(gè)文件夾,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03
maven中snapshot相關(guān)jar無法拉取問題及解決方案(常用方案)
Maven中的SNAPSHOT版本是指正在開發(fā)中的版本,這些版本可能會(huì)頻繁地更新,在使用Maven構(gòu)建項(xiàng)目時(shí),有時(shí)會(huì)遇到無法拉取SNAPSHOT相關(guān)jar的問題,下面給大家分享maven中snapshot相關(guān)jar無法拉取問題及解決方案,感興趣的朋友一起看看吧2024-06-06
淺析java實(shí)現(xiàn)數(shù)據(jù)加密問題
本文通過實(shí)例代碼給大家介紹了java實(shí)現(xiàn)數(shù)據(jù)加密問題,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2019-11-11

