Spring Boot实现邮件验证登录注册

现在很多网站,实现登录或者注册的时候都会用到验证码之类的方式确保安全,Spring Boot,接触Spring Boot没多久,今天完成了Spring Boot 整合邮件服务实现利用邮箱完成注册的功能


这里给一个测试访问地址:180.76.99.142:8080,
所有注释以及全部代码都在下面,方便随时查阅

下面开始从零搭建

1、创建数据库

数据库名:springemail
Spring Boot实现邮件验证登录注册_第1张图片

2、idea创建一个maven工程pom.xml


<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 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0modelVersion>
    <packaging>jarpackaging>

    <name>EmailProname>
    <groupId>site.tiangroupId>
    <artifactId>EmailProartifactId>
    <version>1.0version>
    
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.1.3.RELEASEversion>
    parent>

    <dependencies>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-mailartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
        dependency>
        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druidartifactId>
            <version>1.1.6version>
        dependency>
        
        <dependency>
            <groupId>log4jgroupId>
            <artifactId>log4jartifactId>
            <version>1.2.17version>
        dependency>
        
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-jdbcartifactId>
        dependency>
        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.37version>
        dependency>
        
        <dependency>
            <groupId>tk.mybatisgroupId>
            <artifactId>mapper-spring-boot-starterartifactId>
            <version>2.1.5version>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-thymeleafartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
        dependency>
    dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>

project>

Spring Boot实现邮件验证登录注册_第2张图片

3.工程目录结构

功能虽小但五脏俱全 静态文件下载地址:http://180.76.99.142/jt.zip

4、login页面(其实没必要这么多,纯属好看,登陆注册都在这里面)


<html lang="en" xmlns:th="http://www.thymeleaf.org">
   <head>
      <title>Astronauts sign up & login Form a Flat Responsive Widget Template :: xmoban.cn title>
      
      <meta name="viewport" content="width=device-width, initial-scale=1" />
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      <meta name="keywords" content=" Astronauts sign up & login Form Responsive Widget, Audio and Video players, Login Form Web Template, Flat Pricing Tables, Flat Drop-Downs, Sign-Up Web Templates, Flat Web Templates, Login Sign-up Responsive Web Template, Smartphone Compatible Web Template, Free Web Designs for Nokia, Samsung, LG, Sony Ericsson, Motorola Web Design"
         />
      <script>
         addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false); function hideURLbar(){ window.scrollTo(0,1); }
      script>
      
      
      <link th:href="@{~/css/popuo-box.css}" rel="stylesheet" type="text/css" media="all" />
      
      
      <link th:href="@{~/css/style.css}" rel='stylesheet' type='text/css' media="all">
      
      <link href="//fonts.googleapis.com/css?family=Barlow:300,400,500" rel="stylesheet">
   head>
   <body>
      <h1 class="header-w3ls">
         登录 或者~ 注册
      h1>
      <div class="art-bothside">
         <div class="mid-cls">
            <div class="art-right-w3ls">
               <h2>Astronauts sign up and loginh2>
               <p>consectetur adipiscing elit, sed do eiusmod tempor incididunt Lorem ipsum dolor sit ametp>
               <form id="myForm" th:action="reg" method="post">
                  <div class="main">
                     <div class="form-left-to-w3l">
                        <input type="text" name="username" placeholder="用户名" required="">
                     div>
                     <div class="form-right-w3ls">
                        <input type="email" name="email" placeholder="注册邮箱~ ~ " required="">
                     div>
                  div>
                  <div class="main">
                     <div class="form-left-to-w3l">
                        <input type="password" name="password" placeholder="Password" id="password" required="">
                        <div class="clear">div>
                     div>
                     <div class="form-right-w3ls ">
                        <input type="password" placeholder="Confirm Password" id="confirm_password" required="">
                     div>
                  div>
                  <div class="btnn">
                     <button th:id="submit" type="submit">注册button>
                     <span class="btn-block" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}" style="color: red">span>
                  div>
               form>
               <div class="banner-agileits-btm">
                  <div class="w3layouts_more-buttn">
                     <h3>Already have an account..? <a href="#small-dialog1 " class="play-icon popup-with-zoom-anim">logina>h3>
                  div>
                  <div id="small-dialog1" class="mfp-hide w3ls_small_dialog wthree_pop">
                     <div class="agileits_modal_body">
                        
                        <div class="letter-w3ls">
                           <form id="TowForm"  action="login" method="post">
                              <div class="form-left-to-w3l">
                                 <input type="text" name="username" placeholder="Name" required="">
                              div>
                              <div class="form-right-w3ls">
                                 <input type="email" name="email" placeholder="Email" required="">
                              div>
                              <div class="form-right-w3ls ">
                                 <input type="password" name="password" placeholder="Password" required="">
                              div>
                              <div class="btnn">
                                 <button th:id="login" type="submit">登录button><br>
                              div>
                           form>
                           <div class="clear">div>
                        div>
                        
                     div>
                  div>
               div>
            div>
            <div class="art-left-w3ls">
               <img th:src="@{~/images/right1.jpg}" class="img-fluid" alt="">
            div>
         div>
      div>
      <div class="copy">
         <p>©2020 Astronauts sign up & login Form. All Rights Reserved | Design by
      div>
      
      <script th:src='@{~/js/jquery-2.2.3.min.js}'>script>
      
      <script>
         var password = document.getElementById("password")
           , confirm_password = document.getElementById("confirm_password");
         
         function validatePassword(){
           if(password.value != confirm_password.value) {
             confirm_password.setCustomValidity("Passwords Don't Match");
           } else {
             confirm_password.setCustomValidity('');
           }
         }
         password.onchange = validatePassword;
         confirm_password.onkeyup = validatePassword;
      script>
      
      <script th:src="@{~/js/jquery.magnific-popup.js}">script>
      
      <script>
         $(document).ready(function () {
         	$('.popup-with-zoom-anim').magnificPopup({
         		type: 'inline',
         		fixedContentPos: false,
         		fixedBgPos: true,
         		overflowY: 'auto',
         		closeBtnInside: true,
         		preloader: false,
         		midClick: true,
         		removalDelay: 300,
         		mainClass: 'my-mfp-zoom-in'
         	});
         
         });
      script>
<script>
   $("#submit").click(function () {
      $("#myForm").submit();
   });
   $("#login").click(function () {
      $("#TowForm").submit();
   })
script>
   body>
html>

4.1 、登陆成功后主页面main其实就是从session中取出用户名


<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
head>
<body>
欢迎您:[[${session.user.username}]]
body>
html>

5、yml.xml 文件

#设置默认端口
server:
  port: 8080

#设置启动时加载控制器
spring:
  mail:
    host: smtp.126.com #发送邮件服务器
    username: [email protected] #发送邮件的邮箱地址,这里设置成你们自己的就行
    password: ~~xxxxxxxx~~  #客户端授权码,不是邮箱密码,网易的是自己设置的,百度搜索网易授权码操作获取
    properties.mail.smtp.port: 465 #465或者994
    from: [email protected] # 发送邮件的地址,和上面username一致
    #下面配置有兴趣可以自行查阅
    properties.mail.smtp.starttls.enable: true
    properties.mail.smtp.starttls.required: true
    properties.mail.smtp.ssl.enable: true
    default-encoding: utf-8
  mvc:
    servlet:
      load-on-startup: 1
  datasource: #配置数据源
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/springemail?characterEncoding=utf8
    username: "root"
    password: "tiantian" #这里有一个坑,这种方式的配置数据库即使数据库密码正确,若数据库密码是由纯数字组成的,依然会报错
    type: com.alibaba.druid.pool.DruidDataSource #指定数据源
  thymeleaf: #关闭缓存,防止更改页面不能即使刷新
    cache: false
    mode: HTML5
    encoding: utf-8
#mybatis配置
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: site.tian.pojo
  configuration: #驼峰命名法配置
    map-underscore-to-camel-case: true
#静态资源的访问要放在资源文件夹中才不会被过滤掉,如:static,Public

6、连接数据库还需要配置数据源

package site.tian.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
@Configuration
public class DruidConfig {
    /*配置数据库*/
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druid() {
        return new DruidDataSource();
    }

}

7、为了防止非授权登录,这里简单用拦截器配置一下

package site.tian.interceptor;

import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String user = (String)request.getSession().getAttribute("user");
        if(user == null){
            request.setAttribute("msg","您没有权限,请先登录");
            request.getRequestDispatcher("/login").forward(request,response);
            return false;
        }else {
            return true;
        }
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}

8、把拦截器配置到容器中

package site.tian.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import site.tian.interceptor.LoginInterceptor;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    /*添加拦截器,添加到最上面最好*/
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")
                .excludePathPatterns("/","/checkCode","/reg","/login","/js/**","/css/**","/images/**");
    }
    @Override
    /*设置默认跳转的请求视图*/
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("login");
        registry.addViewController("/login").setViewName("login");
    }
}

9、创建实体类

package site.tian.pojo;

import lombok.Data;
@Data
public class User {
    private Long id;
    private String username;
    private String password;
    private String email;
    /**
     * 状态:0代表未激活,1代表激活
     */
    private Integer status;
    /**
     * 利用UUID生成一段数字,发动到用户邮箱,当用户点击链接时
     * 在做一个校验如果用户传来的code跟我们发生的code一致,更改状态为“1”来激活用户
     */
    private String code;
}

10、OK上面都是准备工作,下面步入正题

10.1

controller

package site.tian.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import site.tian.email.UUIDUtils;
import site.tian.pojo.User;
import site.tian.service.UserService;

import javax.servlet.http.HttpServletRequest;

@Controller
public class LoginController {
    @Autowired
    private UserService userService;

    /*注册*/
    @RequestMapping("/reg")
    public String res(User user, Model model) {
        user.setStatus(0);
        String code = UUIDUtils.getUUID() + UUIDUtils.getUUID();
        user.setCode(code);
        userService.register(user);
        model.addAttribute("msg", "注册成功前往邮箱激活!");
        return "login";
    }

    /**
     * 校验邮箱中的code激活账户
     * 首先根据激活码code查询用户,之后再把状态修改为"1"
     */
    @RequestMapping(value = "/checkCode")
    public String checkCode(String code) {
        User user = userService.checkCode(code);
        System.out.println(user);
        //如果用户不等于null,把用户状态修改status=1
        if (user != null) {
            user.setStatus(1);
            //把code验证码清空,已经不需要了
            user.setCode("");
            System.out.println(user);
            userService.updateUserStatus(user);
        }
        return "login";
    }

    @RequestMapping("/login")
    public String login(User user, HttpServletRequest request) {
        if (user.getPassword() != null && user.getEmail() != null && user.getUsername() != null) {
           User token= userService.login(user);
            request.getSession().setAttribute("user",token);
            return "main";
        }else {
            return "login";
        }
    }

}

10.2 、配置email主要配置有以下几个类

接口

package site.tian.email;

public interface MailService {

    void sendHtmlMail(String to, String subject, String content);
}

实现类

package site.tian.email;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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 javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

@Service
public class MailServiceImpl implements MailService {
    /*开启日志*/
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private JavaMailSender mailSender;
    /**
     * 配置文件中我的qq邮箱
     */
    @Value("${spring.mail.from}")
    private String from;

    /**
     * 发送HTML邮件
     * @param to 收件者
     * @param subject 邮件主题
     * @param content 文本内容
     */
    @Override
    public void sendHtmlMail(String to,String subject,String content) {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = null;
        try {
            helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(subject);
            helper.setTo(to);
            helper.setText(content, true);
            mailSender.send(message);
            //日志信息
            logger.info("邮件已经发送。");
        } catch (MessagingException e) {
            logger.error("发送邮件时发生异常!", e);
        }
    }
}

验证码实现工具类

package site.tian.email;

import java.util.UUID;

public class UUIDUtils {
    public static String getUUID(){
        return UUID.randomUUID().toString().replace("-","");
    }
}

10.3 、业务接口和实现类

接口

package site.tian.service;

        import site.tian.pojo.User;

public interface UserService {
    public void register(User user);

    User checkCode(String code);

    void updateUserStatus(User user);

    User login(User user);
}

实现类

package site.tian.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import site.tian.email.MailService;
import site.tian.mapper.UserMapper;
import site.tian.pojo.User;
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MailService mailService;
    @Override
    public void register(User user) {
        userMapper.insert(user);
        //获取激活码
        String code = user.getCode();
        System.out.println("code:"+code);
        //主题
        String subject = "来自天天网站的激活邮件";
        //激活码是我们点击邮件链接之后根据激活码查询用户,如果存在说明一致,将用户状态修改为“1”激活,有用户来访问服务器
        //上面的激活码发送到用户注册邮箱
        String context = "激活请点击:"+code+"进行激活您的账号";
        //发送激活邮件
        mailService.sendHtmlMail(user.getEmail(),subject,context);
    }

    @Override
    public User checkCode(String code) {
        return userMapper.checkCode(code);
    }

    @Override
    public void updateUserStatus(User user) {
        userMapper.updateUserStatus(user);
    }

    @Override
    public User login(User user) {
        return userMapper.login(user);
    }
}

10.4、mapper文件及对应xml

接口

package site.tian.mapper;


import site.tian.pojo.User;

public interface UserMapper  {

    void insert(User user);

    User checkCode(String code);

    void updateUserStatus(User user);

    User login(User user);
}

xml



<mapper namespace="site.tian.mapper.UserMapper">
    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO user (username,password,status,code,email) VALUES(#{username},#{password},#{status},#{code},#{email}) ;
    insert>
    <update id="updateUserStatus">
        UPDATE user SET status = #{status},code=#{code} WHERE id = #{id} ;
    update>
    <select id="checkCode" resultType="site.tian.pojo.User">
        select * from user where code=#{code}
    select>
    <select id="login" resultType="site.tian.pojo.User">
        select * from user where status=1 and username=#{username} and email=#{email} and password=#{password}
    select>
mapper>

11、上述是所有代码,完结

你可能感兴趣的:(spring,Boot,邮件服务)