保姆级案例Spring boot+Mybatis-Plus+Ajax实现邮箱验证码注册登录

514 阅读3分钟

1、引入依赖包

<dependency>
   <groupId>com.baomidou</groupId>
   <artifactId>mybatis-plus-boot-starter</artifactId>
   <version>3.3.0</version>
</dependency>

<!--邮件服务依赖-->
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
 </dependency>

2、邮箱服务器配置。

此处以163邮箱为例。邮箱的授权码怎么获取自行百度。注:QQ邮箱在发送多次邮件后会被腾讯判定为发送垃圾邮件,然后就不给发了,后台会报错。

#邮箱服务器相关配置
#QQ:smtp.qq.com
#163:pop.163.com
spring.mail.host=smtp.163.com
#QQ:587;
#163邮箱不需要写端口
#spring.mail.port=587
#用户名
spring.mail.username=邮箱号
#密码
spring.mail.password=获取的授权码
#邮件编码格式
spring.mail.default-encoding= UTF-8
#邮件超时设置
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=3000
spring.mail.properties.mail.smtp.writetimeout=5000
#生成随机6位数验证码
my.code=${random.int[100000,999999]}

3、工具类

public class Result<T> {
    private String code;
    private String msg;
    private T data;

    省略get\set

    public static Result success(){
        Result result = new Result<>();
        result.setCode("0");
        result.setMsg("成功");
        return result;
    }

    public static <T> Result<T> success(T data){
        Result<T> result = new Result<>(data);
        result.setCode("0");
        result.setMsg("成功");
        return result;
    }
    public static Result error(String code,String msg){
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }
}

3、前端页面例子

<form>
<div>注册</span>
    <ul>
        <li>
            <input type="text" id="email" maxlength="20" placeholder="邮箱" ></li>
        <li>
            <input type="password" id="password" maxlength="20" placeholder="密码" >
        </li>
        <li>
            <input type="password" id="newPassword" maxlength="20" placeholder="重复密码" >
        </li>
        <li>
            <input type="text" id="code" maxlength="6" placeholder="输入验证码" >
            <button type="button" class="layui-btn layui-btn-normal" id="getCode">获取验证码</button>
        </li>
    </ul>
    <div><span>已有账号?</span><span><a href="">去登录</a></span></div>
    <div class="Login_btn__2NyXD">
        <button type="button" id="register" >提交</button>
    </div>
</div>
</form>

JS部分

<script>
$(function (){
    $("#getCode").click(function (){
        //获取输入邮箱
        var email = $("#email").val().trim();
        //定义变量
        var ok = true;
        //判断输入是够为空
        if (email == null || email == ""){
            layer.msg('邮箱不能为空!');//layui的弹窗
            ok = false;
            //检验输入邮箱是否合规
        }else if (email!=null && email.search(/^\w+((-\w+)|(.\w+))*@[A-Za-z0-9]+((.|-)[A-Za-z0-9]+)*.[A-Za-z0-9]+$/) != -1){
        }else {
            layer.msg('请输入合法的邮箱!');
            ok = false;
        }
if (ok) {
        //发送Ajax请求
        $.ajax({
            url: "",
            type: "get",
            data: {
                "email": email
            },
            dataType: "json",
            success: function (result) {
                if (result.code == -1){
                    layer.msg('用户名已注册!')
                }
                //发送成功
                if (result.code == 0) {
                    layer.msg('验证码已发送!');
                    // 执行按钮倒计时
                    countDown();//执行按钮倒计时
                }
            },

            error: function () {
                alert('验证码发送异常,请稍后再试!')
            }
        })
    }
})
//定义获取验证码按钮倒计时
var maxTime = 60;
//验证码按钮倒计时样式
function countDown(){
    if (maxTime == 0) {
        code = "";
        $("#getCode").removeClass("layui-btn-disabled");
        $("#getCode").removeAttr("disabled")
        $("#getCode").html("获取验证码")
        maxTime = 60;
    } else {
        $("#getCode").attr("disabled", "disabled");
        $("#getCode").addClass("layui-btn-disabled");
        $("#getCode").html(maxTime + "秒后重新获取");
        maxTime--;
        setTimeout(countDown, 1000);
    }
}

    //监听注册按钮
    $("#register").click(function (){
        //获取输入邮箱
        var email = $("#email").val().trim();//下面省略
        //获取输入的密码
        //获取重复密码
        //获取验证码
        //定义变量
        var ok = true;
        //判断省略
        //输入合法成功
        if (ok) {
            //发送Ajax请求
            $.ajax({
                url: "",
                type: "get",
                data: {
                    "email": email,
                    "password":password,
                    "code":code
                },
                dataType: "json",
                success: function (result) {
                    //发送成功
                    if (result.code == 0) {
                        layer.msg('注册成功!');
                        window.location.href="";//成功跳转路径
                    }
                    if (result.code == -1) {
                        layer.msg(result.msg);
                    }
                    if (result.code == 1) {
                        layer.msg(result.msg);
                    }
                    if (result.code == 2) {
                        layer.msg(result.msg);
                    }
                },

                error: function () {
                    alert('注册异常,请稍后再试!')
                }
            })
        }
    })
});
</script>

4、控制层

不要学我全写在控制层,我只是想偷懒 嘿嘿

@RestController
@Slf4j
@RequestMapping("/")
public class UserController {
    /**
     * 服务对象
     */
    @Resource
    private UserDao userDao;
    @Autowired
    private JavaMailSenderImpl javaMailSender;
    @Autowired
    private TemplateEngine templateEngine;
    @Value("${spring.mail.username}")
    private String from;
    @Value("${my.code}")
    private String code;
    
/**
 *
 * 发送验证码
 */
@RequestMapping("/")
@ResponseBody
public Result email(User user, String email, HttpSession session) {
    //查找数据库用户名是否已存在
    User res = userDao.selectOne(Wrappers.<User>lambdaQuery().eq(User::getEmail, user.getEmail()));
        if (res != null) {
            return Result.error("-1", "用户名已存在!");
        }
    MimeMessage message = javaMailSender.createMimeMessage();
    try {
        MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
        helper.setFrom(from);
        helper.setTo(email);
        helper.setSubject("新用户注册");

        Context context = new Context();
        context.setVariable("username", email);
        context.setVariable("code", code);
        //发送邮件模板
        String emailTemplate = templateEngine.process("emailTemplate", context);//emailTemplate为HTML邮件模板
        helper.setText(emailTemplate, true);

        javaMailSender.send(message);
        //验证码存入session
        session.setAttribute("checkCode", code);
        //设置验证码有效时间为300秒
        session.setMaxInactiveInterval(300);//以秒为单位
        log.info("邮件发送成功!验证码为:" + code);

    } catch (MessagingException e) {
        log.error("邮件发送异常!", e);
    }
    return Result.success();
}

/**
 * 账号注册
 */
@RequestMapping("/")
@ResponseBody
public Result<?> register(User user, String code, HttpSession session) {
    try {
        //获取保存到session的验证码
        String checkCode = (String) session.getAttribute("checkCode");
        //查找数据库用户名是否已存在
        User res = userDao.selectOne(Wrappers.<User>lambdaQuery().eq(User::getEmail, user.getEmail()));
        //对比输入验证码是否一致
        if (!code.equals(checkCode) && checkCode != null) {
            return Result.error("1", "验证码有误!");
        }
        //验证码过期
        if (checkCode == null) {
            return Result.error("2", "验证码失效,请重新获取!");
        }
        if (res != null) {
            return Result.error("-1", "用户名重复!");
        }
        //对密码进行md5加密
        String md5pass = DigestUtils.md5DigestAsHex(user.getPassword().getBytes(StandardCharsets.UTF_8));
        user.setPassword(md5pass);
        //成功保存到数据库
        userDao.insert(user);
        //删除保存的验证码
        session.removeAttribute("checkCode");
        log.info("注册成功!");
    } catch (Exception e) {
        log.error("注册异常!", e);
    }
    return Result.success();
}

/**
 * 用户登录
 */
@RequestMapping("/")
@ResponseBody
public Result<?> Login(User user) {
    //对比数据库是否存在此账号
    User email = userDao.selectOne(Wrappers.<User>lambdaQuery().eq(User::getEmail, user.getEmail()));
    //获取输入的密码转换为MD5加密再与数据库进行对比
    String md5pass = DigestUtils.md5DigestAsHex(user.getPassword().getBytes(StandardCharsets.UTF_8));
    //对比数据库的账号和密码
    User res = userDao.selectOne(Wrappers.<User>lambdaQuery().eq(User::getEmail, user.getEmail()).eq(User::getPassword, md5pass));
    try {
        //用户不存在
        if (email == null){
            return Result.error("-1", "用户名不存在,请先注册!");
        }
        if (res == null) {
            return Result.error("1", "密码错误!");
        }
    } catch (Exception e) {
        log.error("登录异常!", e);
    }
    log.info("登录成功!" + user.getEmail());
    //登录成功返回账号数据
    return Result.success(res);
}

5、实体类

放个实体类上来吧,想偷懒来着

public class User {

    private Integer uid;

    private String email;

    private String password;
    省略getset

到此就完成了,未毕业的小菜鸡一枚仅用于记录学习的东西。 验证码还可以返回前端页面存入cookie,注册的时候再取出来对比就好了,session只是其中一种方法,还有其它方法我还得去看看。 每天进步一点点!