郵箱驗證激活賬號




1. 流程

  • 我們注冊賬號的時候會收到一封郵件,點擊郵件里的鏈接就激活賬號,這個功能很常見。其實就是在用戶表里面加statecode字段,state表示激活狀態,code是激活碼
  • 用戶填寫賬號點擊注冊,接着后台就往數據庫插入數據,數據中state字段為0(表示未激活),還有個隨機的code
  • 之后就向該用戶發送郵件,郵件里有一個激活賬號的URL(URL有用戶id和對應的隨機激活碼)
  • 用戶點擊郵件的鏈接,就會帶上用戶id和激活碼來到激活頁面激活賬號,若郵件的參數和數據庫參數一致則激活賬號,更新字段state未為1,否則不激活
  • 這里只介紹最基本的功能,還有激活碼的過期時間,激活不成功刪除賬號,密碼加鹽等細節沒有實現,還有這里的項目沒有前端頁面,一切功能從地址欄實現,請各位酌情考慮


2. 環境與依賴

  • IDEA
  • Maven

依賴

<!--  父工程  -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>

<!--  JDK版本  -->
<properties>
<java.version>1.8</java.version>
</properties>

<!--  各種依賴  -->
<dependencies>


<!--  Web啟動類  -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- 阿里巴巴數據庫連接池  -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.10</version>
</dependency>
<!-- 連接池的啟動器 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
</dependency>

<!--  添加數據庫啟動器  -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--  數據庫驅動,因為springboot不知道我們使用什么數據庫  -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.28</version>
</dependency>
<!--  mybatis依賴  -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>
<!--  mybatis啟動器依賴  -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.2</version>
</dependency>
<!--  Junit依賴  -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--  郵件依賴  -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

SpringBoot配置文件

# 數據庫連接池,自帶hikari
# hikari:
#   maximum-pool-size: 30   # 最大連接數
#   minimum-idle: 10        # 最小連接數


# 自己的郵件配置
Howl:
  mail:
    from: XXXXXXXXXX@qq.com
    subject: 激活郵件
    address: http://localhost:8080


spring:
  # 數據源
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC
    username: root
    password:
      druid:
        initial-size: 10
        min-idle: 5
        max-active: 20
        pool-prepared-statements: true

  # 郵件配置
  mail:
    host: smtp.qq.com
    port: 465
    username: XXXXXXXXXX@qq.com
    password: XXXXXXXXXXXXXXXXXX  #這里是smtp的密碼,不是QQ密碼
    protocol: smtp
    default-encoding: utf-8
    properties:
      mail:
        imap:
          ssl:
            socketFactory:
              fallback: false
        smtp:
          auth: true
          ssl:
            enable: true
            socketFactory:
              class: com.fintech.modules.base.util.mail.MailSSLSocketFactory
          starttls:
            enable: true
            required: true
      test-connection: false


# mybatis配置
mybatis:
  # 別名
  type-aliases-package: com.howl.dto
  # 映射文件路徑,一般不用了
  # mapper-locations: classpath:mappers/*.xml
  configuration:
    # 開啟駝峰映射
    map-underscore-to-camel-case: true


2. 項目結構



3. 數據庫

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  `state` int(1) NOT NULL DEFAULT '0' COMMENT '用戶激活狀態:0表示未激活,1表示激活',
  `code` varchar(255) NOT NULL COMMENT '激活碼',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


4. DTO層

public class User {

    private int id;
    private String username;
    private String password;
    private String email;
    private String state;
    private String code;

	//Getters、Setters
    //Constructor
}


5. DAO層

  • 使用mybatis動態代理,編寫的是接口
@Mapper
public interface UserMapper {

    @Options(useGeneratedKeys = true, keyProperty = "id")
    @Insert("INSERT INTO user (`username`,`password`,`email`,`code`) VALUES (#{username},#{password},#{email},#{code})")
    public int register(User user);

    @Select("SELECT * FROM user WHERE id = #{id}")
    public User getUserById(int id);

    @Update("UPDATE user SET state = 1 WHERE id = #{id} AND code = #{code}")
    public int updateByIdAndCode(int id, String code);
}


6. 工具類

郵件工具類

@Component
public class EmailUtil {

    @Autowired
    private JavaMailSender javaMailSender;

    @Value("${Howl.mail.from}")
    private String from;
    @Value("${Howl.mail.subject}")
    private String subject;
    @Value("${Howl.mail.address}")
    private String address;

    public void sendEmail(int id, String code, String to) {

        String url = address + "/verify?id=" + id + "&code=" + code;
        String label = "<a href=" + url + ">點擊此處激活賬號,有沒有反應可以復制鏈接從瀏覽器打開</a>";

        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true);
            messageHelper.setFrom(from);
            messageHelper.setTo(to);
            messageHelper.setSubject(subject);
            messageHelper.setText(label,true);
            messageHelper.setSentDate(new Date());
            javaMailSender.send(mimeMessage);
        }catch (Exception e){
            new RuntimeException("郵件發送失敗",e);
        }
    }
}

激活碼

@Component
public class CodeUtil {

    public String getCode() {

        //返回UUID
        return UUID.randomUUID().toString().replace("-", "");
    }
}


7. Service層

@Service
public class UserService {

    @Autowired
    UserMapper userMapper;
    @Autowired
    EmailUtil emailUtil;
    @Autowired
    CodeUtil codeUtil;

    public int register(String username, String password, String email) {

        int result;
        String code = codeUtil.getCode();
        User user = new User(username, password, email, code);
        result = userMapper.register(user);

        // 開線程來發郵件,提高效率,發郵件很慢
        new Thread(() -> {
            emailUtil.sendEmail(user.getId(), code, email);
        }).run();
        return result;
    }

    public int verify(int id, String code) {

        User user = userMapper.getUserById(id);
        if (user != null) {
            return userMapper.updateByIdAndCode(id, code);
        }
        return 0;
    }
}


8. Controller層

@RestController
public class UserController {

    @Autowired
    UserService userService;

    @GetMapping(value = "/register")
    public String register(String username, String password, String email) {
        return userService.register(username, password, email) + "";
    }

    @GetMapping(value = "/verify")
    public String verify(int id, String code) {
        return userService.verify(id, code) + "";
    }
}


9. SpringBoot入口

@SpringBootApplication
@MapperScan("com.howl.dao")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}


10. 測試

都看到這里了,沒有前端頁面。。。大家自行想象登錄操作


10.1 注冊

這里使用地址欄GET方式注冊,正式注冊用POST表單的不要學我,為了懶不想寫前端

10.2 數據庫插入

10.3 收郵件

10.4 點擊鏈接激活

10.5 查看數據庫激活狀態



總結

實現太簡單,不過基本功能還是有的,細節方面可以慢慢補充




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM