郵箱驗證激活帳號



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配置文件java

# 數據庫鏈接池,自帶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. 工具類

郵件工具類mysql

@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);
        }
    }
}

激活碼web

@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. 測試

都看到這裏了,沒有前端頁面。。。你們自行想象登陸操做spring


10.1 註冊

這裏使用地址欄GET方式註冊,正式註冊用POST表單的不要學我,爲了懶不想寫前端sql

10.2 數據庫插入

10.3 收郵件

10.4 點擊連接激活

10.5 查看數據庫激活狀態




總結數據庫

實現太簡單,不過基本功能仍是有的,細節方面能夠慢慢補充瀏覽器

相關文章
相關標籤/搜索