最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot如何使用mail實(shí)現(xiàn)登錄郵箱驗(yàn)證

 更新時(shí)間:2024年06月28日 15:22:50   作者:熊哈哈O_o  
在實(shí)際的開發(fā)當(dāng)中,不少的場(chǎng)景中需要我們使用更加安全的認(rèn)證方式,同時(shí)也為了防止一些用戶惡意注冊(cè),我們可能會(huì)需要用戶使用一些可以證明個(gè)人身份的注冊(cè)方式,如短信驗(yàn)證、郵箱驗(yàn)證等,這篇文章主要介紹了SpringBoot如何使用mail實(shí)現(xiàn)登錄郵箱驗(yàn)證,需要的朋友可以參考下

在實(shí)際的開發(fā)當(dāng)中,不少的場(chǎng)景中需要我們使用更加安全的認(rèn)證方式,同時(shí)也為了防止一些用戶惡意注冊(cè),我們可能會(huì)需要用戶使用一些可以證明個(gè)人身份的注冊(cè)方式,如短信驗(yàn)證、郵箱驗(yàn)證等。

一、前期準(zhǔn)備

為了實(shí)現(xiàn)郵箱認(rèn)證服務(wù),我們需要提供出來(lái)一個(gè)郵箱作為驗(yàn)證碼的發(fā)送者,這里我使用的是QQ郵箱。

1 開啟郵箱服務(wù)

首先打開QQ郵箱,然后找到設(shè)置,點(diǎn)擊賬號(hào)。

然后找到下方的郵件協(xié)議服務(wù),打開。因?yàn)檫@里我已經(jīng)打開了,而且服務(wù)開啟也較為簡(jiǎn)單,需要我們發(fā)送一個(gè)短信到指定的號(hào)碼,可能會(huì)收取一定的費(fèi)用,不過(guò)不是很多,好像是幾毛錢。

 開啟之后會(huì)給你一個(gè)授權(quán)碼,一定要記住這個(gè)授權(quán)碼,發(fā)郵件的時(shí)候需要這個(gè)。

2 SpringBoot導(dǎo)入依賴

核心的就是mail依賴,因?yàn)槲疫@個(gè)項(xiàng)目東西不少,為了方便我就全拷貝過(guò)來(lái)了,可能有的用不到。

 <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.7.6</spring-boot.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <mybatisplus.version>3.4.3.1</mybatisplus.version>
        <mybatisplus.generator>3.3.2</mybatisplus.generator>
        <mybatisplus.velocity>1.7</mybatisplus.velocity>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
        </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>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatisplus.version}</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>${mybatisplus.generator}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>${mybatisplus.velocity}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.56</version>
        </dependency>
    </dependencies>

3 創(chuàng)建application.yml配置文件 

spring:
  #郵件服務(wù)配置
  mail:
    host: smtp.qq.com #郵件服務(wù)器地址
    protocol: smtp #協(xié)議
    username:  #發(fā)送郵件的郵箱也就是你開通服務(wù)的郵箱
    password:  #開通服務(wù)后得到的授權(quán)碼
    default-encoding: utf-8 #郵件內(nèi)容的編碼
  redis:
    host: 127.0.0.1
    port: 6379
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mail
    username: root
    password:  # 數(shù)據(jù)庫(kù)的密碼

4 創(chuàng)建數(shù)據(jù)庫(kù)文件

在上邊的配置文件中你也看到了,我們用到了mysql還有redis。

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `account` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Compact;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'admin', '123456');
INSERT INTO `user` VALUES (2, '123456', '123456');
SET FOREIGN_KEY_CHECKS = 1;

 5 配置redis服務(wù)

在之前的文章當(dāng)中我有說(shuō)到過(guò)安裝redis的事情,大家可以看看我這篇文章。【Spring】SpringBoot整合Redis,用Redis實(shí)現(xiàn)限流(附Redis解壓包)_springboot 限流 

二、驗(yàn)證郵件發(fā)送功能 

大家可以先看一下我的項(xiàng)目結(jié)構(gòu)。其中的一些代碼是我參考學(xué)習(xí)另一位大佬的文章,這篇文章也是對(duì)該大佬文章的一個(gè)總結(jié)。參考資料:蒾酒

我們最重要的郵件發(fā)送工具 就是util包下的EmailApi。將以下代碼導(dǎo)入后,創(chuàng)建一個(gè)測(cè)試方法。

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.Objects;
/**
 * @author mijiupro
 */
@Component
@Slf4j
public class EmailApi {
    @Resource
    private JavaMailSender mailSender;
    @Value("${spring.mail.username}")
    private String from ;// 發(fā)件人
    /**
     * 發(fā)送純文本的郵件
     * @param to 收件人
     * @param subject 主題
     * @param content 內(nèi)容
     * @return 是否成功
     */
    @SneakyThrows(Exception.class)
    public boolean sendGeneralEmail(String subject, String content, String... to){
        // 創(chuàng)建郵件消息
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        // 設(shè)置收件人
        message.setTo(to);
        // 設(shè)置郵件主題
        message.setSubject(subject);
        // 設(shè)置郵件內(nèi)容
        message.setText(content);
        // 發(fā)送郵件
        mailSender.send(message);
        return true;
    }
    /**
     * 發(fā)送html的郵件
     * @param to 收件人
     * @param subject 主題
     * @param content 內(nèi)容
     * @return 是否成功
     */
    @SneakyThrows(Exception.class)
    public boolean sendHtmlEmail(String subject, String content, String... to){
        // 創(chuàng)建郵件消息
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
        helper.setFrom(from);
        // 設(shè)置收件人
        helper.setTo(to);
        // 設(shè)置郵件主題
        helper.setSubject(subject);
        // 設(shè)置郵件內(nèi)容
        helper.setText(content, true);
        // 發(fā)送郵件
        mailSender.send(mimeMessage);
        log.info("發(fā)送郵件成功");
        return true;
    }
    /**
     * 發(fā)送帶附件的郵件
     * @param to 收件人
     * @param subject 主題
     * @param content 內(nèi)容
     * @param filePaths 附件路徑
     * @return 是否成功
     */
    @SneakyThrows(Exception.class)
    public boolean sendAttachmentsEmail(String subject, String content, String[] to, String[] filePaths) {
        // 創(chuàng)建郵件消息
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
        helper.setFrom(from);
        // 設(shè)置收件人
        helper.setTo(to);
        // 設(shè)置郵件主題
        helper.setSubject(subject);
        // 設(shè)置郵件內(nèi)容
        helper.setText(content,true);
        // 添加附件
        if (filePaths != null) {
            for (String filePath : filePaths) {
                FileSystemResource file = new FileSystemResource(new File(filePath));
                helper.addAttachment(Objects.requireNonNull(file.getFilename()), file);
            }
        }
        // 發(fā)送郵件
        mailSender.send(mimeMessage);
        return true;
    }
    /**
     * 發(fā)送帶靜態(tài)資源的郵件
     * @param to 收件人
     * @param subject 主題
     * @param content 內(nèi)容
     * @param rscPath 靜態(tài)資源路徑
     * @param rscId 靜態(tài)資源id
     * @return 是否成功
     */
    @SneakyThrows(Exception.class)
    public boolean sendInlineResourceEmail(String subject, String content, String to, String rscPath, String rscId) {
        // 創(chuàng)建郵件消息
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
        // 設(shè)置發(fā)件人
        helper.setFrom(from);
        // 設(shè)置收件人
        helper.setTo(to);
        // 設(shè)置郵件主題
        helper.setSubject(subject);
        //html內(nèi)容圖片
        String contentHtml = "<html><body>這是郵件的內(nèi)容,包含一個(gè)圖片:<img src=\'cid:" + rscId + "\'>"+content+"</body></html>";
        helper.setText(contentHtml, true);
        //指定講資源地址
        FileSystemResource res = new FileSystemResource(new File(rscPath));
        helper.addInline(rscId, res);
        mailSender.send(mimeMessage);
        return true;
    }
}

 進(jìn)行郵件發(fā)送的測(cè)試。

 看看結(jié)果,成功的發(fā)過(guò)來(lái)了。

 接下來(lái)就要進(jìn)行登錄注冊(cè)功能的開發(fā)了。

三、注冊(cè)功能實(shí)現(xiàn)郵箱驗(yàn)證

1 創(chuàng)建User實(shí)體類

@Data
@EqualsAndHashCode(callSuper = false)
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    private String account;
    private String password;
}

2 創(chuàng)建UserParam

@Data
@EqualsAndHashCode(callSuper = false)
public class UserParam implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    private String account;
    private String password;
    private String emailCode;
    private String email;
}

3 創(chuàng)建CaptchaService

public interface CaptchaService {
    boolean sendCaptcha(String email);
}

4 創(chuàng)建EmailTemplateEnum

這一步我沒(méi)有選擇創(chuàng)建CaptchaServiceImpl,因?yàn)檫@個(gè)類中涉及到了一些核心的代碼,而我們一些類還沒(méi)有創(chuàng)建完,我們先創(chuàng)建這樣的一個(gè)枚舉類,這個(gè)枚舉類的作用就是定義我們發(fā)送郵件的一個(gè)模板,我們?cè)诎l(fā)送郵件的時(shí)候,直接向模板內(nèi)插入內(nèi)容就可以了。

ublic enum EmailTemplateEnum {
    // 驗(yàn)證碼郵件
    VERIFICATION_CODE_EMAIL_HTML("<html><body>用戶你好,你的驗(yàn)證碼是:<h1>%s</h1>請(qǐng)?jiān)谖宸昼妰?nèi)完成注冊(cè)</body></html>","登錄驗(yàn)證"),
    // 用戶被封禁郵件通知
    USER_BANNED_EMAIL("用戶你好,你已經(jīng)被管理員封禁,封禁原因:%s", "封禁通知");
    private final String template;
    private final String subject;
    EmailTemplateEnum(String template, String subject) {
        this.template = template;
        this.subject = subject;
    }
    public String getTemplate(){
        return this.template;
    }
    public String set(String captcha) {
        return String.format(this.template, captcha);
    }
    public String getSubject() {
        return this.subject;
    }
}

5 創(chuàng)建CaptchaServiceImpl

首先把我們前端傳過(guò)來(lái)的郵箱加一個(gè)前綴,用于redis中的存儲(chǔ),因?yàn)槲覀儾粌H可以有郵箱認(rèn)證還可以有手機(jī)認(rèn)證。

 @Resource
    StringRedisTemplate stringRedisTemplate;
    @Resource
    EmailApi emailApi;
    @Override
    public boolean sendCaptcha(String email) {
        sendMailCaptcha("login:email:captcha:"+email);
        return true;
    }

 在redis當(dāng)中,驗(yàn)證碼的存儲(chǔ)使用的是Hash結(jié)構(gòu),Hash存儲(chǔ)了驗(yàn)證碼,驗(yàn)證次數(shù),還有上一次的發(fā)送時(shí)間,因?yàn)槲覀円拗埔环昼姲l(fā)送的次數(shù)。一分鐘內(nèi)我們只能發(fā)一條短信,驗(yàn)證碼在redis中的過(guò)期時(shí)間為五分鐘,在驗(yàn)證碼未過(guò)期之前發(fā)送的認(rèn)證,都會(huì)讓這個(gè)發(fā)送次數(shù)加一,倘若發(fā)送的次數(shù)達(dá)到了5次還要發(fā)送,那么就封禁一天不讓發(fā)送短信。

例如,在3:30:30的時(shí)候發(fā)送了一次短信,一分鐘后,3:31:30的時(shí)候又發(fā)送了短信,直到3:35:30的時(shí)候又發(fā)了一次,此時(shí)的發(fā)送次數(shù)已經(jīng)達(dá)到了5,這時(shí)候就會(huì)封一天,因?yàn)槊看伟l(fā)送驗(yàn)證碼的時(shí)候,redis都存儲(chǔ)著上一次還沒(méi)過(guò)期的驗(yàn)證碼,所以發(fā)送次數(shù)會(huì)增加。

下邊講一下代碼。

先從redis中找到這個(gè)hash結(jié)構(gòu),如果hash結(jié)構(gòu)的值不為空并且達(dá)到了發(fā)送次數(shù)上限,就封禁一天,否則的話看一下上一次的發(fā)送時(shí)間是否存在,如果存在的話,判斷一下當(dāng)前時(shí)間和上一次的發(fā)送時(shí)間間隔是否大于60秒,如果小于60秒那么不讓發(fā)送。如果正常發(fā)送短信,那么就把發(fā)送的次數(shù)加1,然后用隨機(jī)數(shù)生成一個(gè)六位數(shù)的驗(yàn)證碼,發(fā)送驗(yàn)證碼,并且向redis中保存剛才的hash結(jié)構(gòu)。

  private boolean sendMailCaptcha(String key){
        BoundHashOperations<String, String, String> hashOps = stringRedisTemplate.boundHashOps(key);
        // 初始檢查
        String lastSendTimestamp = hashOps.get("lastSendTimestamp");
        String sendCount = hashOps.get("sendCount");
        if(StringUtils.isNotBlank(sendCount)&&Integer.parseInt(sendCount)>=5){
            hashOps.expire(24, TimeUnit.HOURS);
            throw new  RuntimeException("驗(yàn)證碼發(fā)送過(guò)于頻繁");
        }
        if(StringUtils.isNotBlank(lastSendTimestamp)){
            long lastSendTime = Long.parseLong(lastSendTimestamp);
            long currentTime = System.currentTimeMillis();
            long elapsedTime = currentTime - lastSendTime;
            if(elapsedTime < 60 * 1000){
                throw new  RuntimeException("驗(yàn)證碼發(fā)送過(guò)于頻繁");
            }
        }
        int newSendCount = StringUtils.isNotBlank(sendCount) ? Integer.parseInt(sendCount) + 1 : 1;
        String captcha = RandomStringUtils.randomNumeric(6);
        try {
            sendCaptcha(key,captcha);
        } catch (Exception e) {
            return false;
        }
        hashOps.put("captcha", captcha);
        hashOps.put("lastSendTimestamp", String.valueOf(System.currentTimeMillis()));
        hashOps.put("sendCount", String.valueOf(newSendCount));
        hashOps.expire(5, TimeUnit.MINUTES); // 設(shè)置過(guò)期時(shí)間為5分鐘
        return true;
    }

發(fā)送驗(yàn)證碼調(diào)用的是下邊的函數(shù)。

 private void sendCaptcha(String hashKey, String captcha) thorw Exception{
        // 根據(jù)hashKey判斷是發(fā)送郵件還是短信,然后調(diào)用相應(yīng)的發(fā)送方法
        if("email".equals(hashKey.split(":")[1])){
            if (!emailApi.sendHtmlEmail(EmailTemplateEnum.VERIFICATION_CODE_EMAIL_HTML.getSubject(),
                    EmailTemplateEnum.VERIFICATION_CODE_EMAIL_HTML.set(captcha),hashKey.split(":")[3])) {
                throw new RuntimeException("發(fā)送郵件失敗");
            }
        }
    }

 6 創(chuàng)建CaptchaController

@RestController
@RequestMapping("/captcha")
public class CaptchaController {
    @Resource
    CaptchaService captchaService;
    @Resource
    EmailApi emailApi;
    @RequestMapping("/getCaptcha")
    public Result sendCaptcha(String email){
        boolean res = captchaService.sendCaptcha(email);
        if(res){
            return new Result("發(fā)送成功",200,null);
        }
        return new Result("發(fā)送失敗",500,null);
    }
}

7 創(chuàng)建LoginController 

UserSevice的東西都很簡(jiǎn)單,都是mybatisplus的內(nèi)容,如果不太了解可以看我這篇文章【Spring】SpringBoot整合MybatisPlus的基本應(yīng)用_簡(jiǎn)單的springboot+mybatisplus的應(yīng)用程序

我這里并沒(méi)有用UserService封裝認(rèn)證的過(guò)程,直接寫到controller中了,大家能看懂就好。僅供學(xué)習(xí)使用。 

@Controller
public class LoginController {
    @Autowired
    UserService userService;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @GetMapping("/")
    public String Login(){
        return "redirect:/pages/login.html";
    }
    @RequestMapping("/register")
    @ResponseBody
    public Result registerUser( UserParam user ){
        String email = user.getEmail();
        String emailCode = user.getEmailCode();
        BoundHashOperations<String, String, String> hashOps = stringRedisTemplate.boundHashOps("login:email:captcha:"+email);
        String code = hashOps.get("captcha");
        if(!Objects.equals(code, emailCode)){
            return new Result("驗(yàn)證碼錯(cuò)誤",400,null);
        }
        User user1 = userService.getOne(new LambdaQueryWrapper<User>()
                .eq(User::getAccount,user.getAccount()));
        //如果有這個(gè)用戶的信息要拒絕注冊(cè)
        if(user1!=null){
            return new Result("",100,null);
        }
        User saveUser = new User();
        BeanUtils.copyProperties(user,saveUser);
        System.out.println(user);
        System.out.println(saveUser);
        boolean save = userService.save(saveUser);
        if(!save){
            return new Result("注冊(cè)失敗",300,null);
        }
        return new Result("注冊(cè)成功",200,null);
    }
}

到此為止,驗(yàn)證碼的注冊(cè)功能就已經(jīng)實(shí)現(xiàn)完成了。

我們現(xiàn)在要做一個(gè)前端頁(yè)面。

四、創(chuàng)建登陸頁(yè)面 

在resources目錄下創(chuàng)建static文件夾。在pages目錄下添加login.html和register.html。至于jquery呢就要大家自己去找了。

1 login.html 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/jquery.min.js"></script>
    <script>
        $(function() {
            $(".btn").on("click", function () {
                var account = $(".account").val()
                var password = $(".password").val()
                console.log(account)
                console.log(password)
                $.ajax({
                    type: "get",
                    url: "/login?&account=" + account + "&password=" + password,
                    success: function (data) {
                        if (data.code === 200) {
                            window.location.href = "../pages/index.html"
                        }else{
                            alert("登陸失敗,請(qǐng)檢查賬號(hào)或者密碼")
                        }
                    }
                })
            })
        });
    </script>
    <style>
        *{
            padding: 0;
            margin: 0px;
            text-decoration: none;
        }
        body {
            background-image: url(../images2/1.jpg);
            background-size:cover;
            background-attachment:fixed;
        }
        .loginbox {
            height: 280px;
            width: 26%;
            margin: 340px auto;
            background-color: rgb(158, 151, 158);
            opacity: 0.7;
            text-align: center;
        }
        .loginbox .top {
            display: block;
            height: 42px;
            background: linear-gradient(90deg,pink,red,pink,yellow,red);
            padding-top: 15px;
            font-size: 20px;
            font-weight: 600;
            color: black;
        }
        .loginbox span {
            color: black;
            font-weight: 500;
            font-size: 18px;
        }
        .loginbox input[type=text],
        .loginbox input[type=password] {
            height: 20px;
            border: none;
            border-radius: 4px;
            outline: none;
        }
        .loginbox input[type=button] {
            width: 40%;
            height: 24px;
            border: none;
            border-radius: 4px;
            margin: 0 auto;
            outline: none;
        }
        .loginbox .a {
            display: flex;
            margin: 20px auto;
            width: 45%;
            justify-content: space-between;
        }
        .loginbox .a a {
            color: white;
        }
        .loginbox .a a:hover {
            color: rgb(228, 221, 228);
        }
    </style>
</head>
<body>
    <div class="loginbox">
        <span class="top">郵箱簡(jiǎn)易發(fā)送系統(tǒng)</span><br>
        <span>賬號(hào):</span>
        <input type="text" placeholder="請(qǐng)輸入賬號(hào)" class="account"><br><br>
        <span>密碼:</span>
        <input type="password" placeholder="請(qǐng)輸入密碼" class="password"><br><br>
        <input type="button" value="登錄" class="btn">
        <div class="a">
            <a href="register.html" rel="external nofollow" >注冊(cè)</a>
            <a href="">忘記密碼</a>
        </div>
    </div>
</body>
</html>

2 register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="../css/register.css" rel="external nofollow" >
    <script src="../js/jquery.min.js"></script>
    <script>
        $(function(){
            // 注冊(cè)按鈕點(diǎn)擊事件
            $(".btn").on("click",function(){
                var account = $(".account").val().trim();
                var password = $(".password").val().trim();
                var emailCode = $(".emailCode").val().trim();
                var email = $(".email").val().trim();
                $.ajax({
                    type:"post",
                    url:"/register",
                    data:{"account":account,"password":password,"emailCode":emailCode,"email":email},
                    success:function(data){
                        if(data.code=== 100){
                            alert("該賬號(hào)已存在");
                        }else if(data.code === 300){
                            alert("賬號(hào)注冊(cè)失敗");
                        }else if(data.code === 400){
                            alert("驗(yàn)證碼錯(cuò)誤");
                        }else{
                            alert("賬號(hào)注冊(cè)成功");
                            window.location.href="../pages/login.html" rel="external nofollow" ;
                        }
                    }
                });
            });
            // 發(fā)送驗(yàn)證碼按鈕點(diǎn)擊事件
            $(".sendCode").on("click", function(){
                var email = $(".email").val().trim();
                if(email === "") {
                    alert("請(qǐng)輸入郵箱");
                    return;
                }
                // 發(fā)送驗(yàn)證碼請(qǐng)求
                $.ajax({
                    type:"get",
                    url:"/captcha/getCaptcha?email="+email,
                    success:function(data){
                        console.log(data)
                        if(data.code === 200){
                            alert("驗(yàn)證碼已發(fā)送到郵箱");
                            // 啟動(dòng)倒計(jì)時(shí)
                            startCountdown(60);
                        } else {
                            alert("驗(yàn)證碼發(fā)送失敗,請(qǐng)重試");
                        }
                    }
                });
            });
            // 啟動(dòng)倒計(jì)時(shí)函數(shù)
            function startCountdown(seconds) {
                var timer = seconds;
                $(".sendCode").prop("disabled", true);
                var countdown = setInterval(function() {
                    $(".sendCode").val(timer + "秒后可重新發(fā)送");
                    timer--;
                    if (timer < 0) {
                        clearInterval(countdown);
                        $(".sendCode").prop("disabled", false);
                        $(".sendCode").val("發(fā)送驗(yàn)證碼");
                    }
                }, 1000);
            }
        });
    </script>
    <style>
        *{
            padding: 0;
            margin: 0px;
            text-decoration: none;
        }
        body {
            background-image: url(../images2/1.jpg);
            background-size: cover;
            background-attachment: fixed;
        }
        .loginbox {
            height: 380px; /* 調(diào)整高度以適應(yīng)新字段 */
            width: 26%;
            margin: 340px auto;
            background-color: rgb(158, 151, 158);
            opacity: 0.7;
            text-align: center;
        }
        .loginbox .top {
            display: block;
            height: 42px;
            background: linear-gradient(90deg, pink, red, pink, yellow, red);
            padding-top: 15px;
            font-size: 20px;
            font-weight: 600;
            color: black;
        }
        .loginbox span {
            color: black;
            font-weight: 500;
            font-size: 18px;
        }
        .loginbox input[type=text],
        .loginbox input[type=password] {
            height: 20px;
            border: none;
            border-radius: 4px;
            outline: none;
        }
        .loginbox input[type=button] {
            width: 40%;
            height: 24px;
            border: none;
            border-radius: 4px;
            margin: 0 auto;
            outline: none;
        }
        .loginbox .a {
            display: flex;
            margin: 20px auto;
            width: 45%;
            justify-content: space-between;
        }
        .loginbox .a a {
            color: white;
        }
        .loginbox .a a:hover {
            color: rgb(228, 221, 228);
        }
    </style>
</head>
<body>
<div class="loginbox">
    <span class="top">郵箱簡(jiǎn)易發(fā)送系統(tǒng)</span><br>
    <span>賬號(hào):</span>
    <input type="text" placeholder="請(qǐng)輸入賬號(hào)" class="account"><br><br>
    <span>密碼:</span>
    <input type="password" placeholder="請(qǐng)輸入密碼" class="password"><br><br>
    <span>郵箱:</span>
    <input type="text" placeholder="請(qǐng)輸入郵箱" class="email"><br><br>
    <input type="button" value="發(fā)送驗(yàn)證碼" class="sendCode"><br><br>
    <span>驗(yàn)證碼:</span>
    <input type="text" placeholder="請(qǐng)輸入驗(yàn)證碼" class="emailCode"><br><br>
    <input type="button" value="注冊(cè)" class="btn">
    <div class="a">
        <a href="login.html" rel="external nofollow" >返回</a>
    </div>
</div>
</body>
</html>

到此這篇關(guān)于SpringBoot使用mail實(shí)現(xiàn)登錄郵箱驗(yàn)證的文章就介紹到這了,更多相關(guān)SpringBoot登錄郵箱驗(yàn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文搞懂設(shè)計(jì)模式中的單例模式

    一文搞懂設(shè)計(jì)模式中的單例模式

    這篇文章主要介紹了一文搞懂設(shè)計(jì)模式中的單例模式,單例模式是最簡(jiǎn)單的設(shè)計(jì)模式之一,屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的方式,確保只有單個(gè)對(duì)象被創(chuàng)建,需要的朋友可以參考下
    2023-08-08
  • Java使用easyExcel實(shí)現(xiàn)導(dǎo)入功能

    Java使用easyExcel實(shí)現(xiàn)導(dǎo)入功能

    這篇文章介紹了Java使用easyExcel實(shí)現(xiàn)導(dǎo)入功能的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-10-10
  • Netty分布式客戶端處理接入事件handle源碼解析

    Netty分布式客戶端處理接入事件handle源碼解析

    這篇文章主要為大家介紹了Netty源碼分析客戶端流程處理接入事件handle創(chuàng)建,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • 詳解MyBatis多數(shù)據(jù)源配置(讀寫分離)

    詳解MyBatis多數(shù)據(jù)源配置(讀寫分離)

    這篇文章主要介紹了詳解MyBatis多數(shù)據(jù)源配置(讀寫分離),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-01-01
  • Java實(shí)現(xiàn)HashMap排序方法的示例詳解

    Java實(shí)現(xiàn)HashMap排序方法的示例詳解

    這篇文章主要通過(guò)一些示例為大家介紹了Java對(duì)HashMap進(jìn)行排序的方法,幫助大家更好的理解和使用Java,感興趣的朋友可以了解一下
    2022-05-05
  • 基于指針pointers和引用references的區(qū)別分析

    基于指針pointers和引用references的區(qū)別分析

    本篇文章介紹了,基于指針pointers和引用references的區(qū)別分析。需要的朋友參考下
    2013-05-05
  • Springcloud服務(wù)注冊(cè)consul客戶端過(guò)程解析

    Springcloud服務(wù)注冊(cè)consul客戶端過(guò)程解析

    這篇文章主要介紹了Springcloud服務(wù)注冊(cè)consul客戶端過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Java實(shí)現(xiàn)markdown格式內(nèi)容轉(zhuǎn)換為word

    Java實(shí)現(xiàn)markdown格式內(nèi)容轉(zhuǎn)換為word

    這篇文章主要為大家簡(jiǎn)單介紹了如何利用Java實(shí)現(xiàn)markdown格式內(nèi)容轉(zhuǎn)換為word文檔,文中的示例代碼簡(jiǎn)潔易懂,有需要的小伙伴可以參考一下
    2025-03-03
  • Java 虛擬機(jī)(JVM)之基本概念詳解

    Java 虛擬機(jī)(JVM)之基本概念詳解

    下面小編就為大家?guī)?lái)一篇Java 虛擬機(jī)(JVM)之基本概念詳解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • Java中Buffer緩沖區(qū)的ByteBuffer類詳解

    Java中Buffer緩沖區(qū)的ByteBuffer類詳解

    這篇文章主要介紹了Java中Buffer緩沖區(qū)的ByteBuffer類詳解,ByteBuffer類是Java NIO庫(kù)中的一個(gè)重要類,用于處理字節(jié)數(shù)據(jù),它提供了一種靈活的方式來(lái)讀取、寫入和操作字節(jié)數(shù)據(jù),ByteBuffer類是一個(gè)抽象類,可以通過(guò)靜態(tài)方法創(chuàng)建不同類型的ByteBuffer對(duì)象,需要的朋友可以參考下
    2023-10-10

最新評(píng)論

枣阳市| 四川省| 曲靖市| 甘南县| 万宁市| 色达县| 睢宁县| 济南市| 乌兰县| 凯里市| 文化| 林州市| 海伦市| 海城市| 新平| 奇台县| 阜南县| 乐安县| 莱西市| 五河县| 新绛县| 平谷区| 陵水| 永胜县| 怀宁县| 汝阳县| 丰原市| 淳化县| 广水市| 揭阳市| 容城县| 崇义县| 古浪县| 嘉定区| 大余县| 浦江县| 大关县| 苗栗市| 江源县| 聂荣县| 阳泉市|