SSM + ajax + LayUI 实现验证码发送



需求描述

想要实现一个验证码登录功能, 也就是用户直接使用邮箱注册, 加入存在该邮箱验证过的用户就直接登录; 不存在就提示让其注册账号, 完成数据绑定


效果

image-20220610111823523 image-20220610111840070 image-20220610111840070

代码实现

引入依赖

<!--邮件发送-->
<!--spring支持-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>5.0.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.1</version>
</dependency>

书写 properties 文件

mail.properties

#服务器主机名 smtp.xx.com
mail.smtp.host=smtp.qq.com
#若无法识别可以写IP地址58.251.106.181,此处可能会用在部署到云服务器运行时设置
mail.smtp.username=XXXX@qq.com
#密码/客户端授权码 - 需要在 qq邮箱中开启授权(设置里面)
mail.smtp.password=
#编码字符
mail.smtp.defaultEncoding=utf-8
#是否进行用户名密码校验
mail.smtp.auth=true
#设置超时时间
mail.smtp.timeout=20000

注册 bean 类

注意: 如果有多个 bean 注入, 比如还有数据库注入的话, 需要在每个 bean 的后面写 ignore-unresolvable="true", 否则会提示找不到 bean 类

applicationContext.xml

<!--邮件配置-->
    <!--
            读取邮件配置文件,
            其中ignore-unresolvable="true"属性是配置文件中存在
            多个property-placeholder时出现解析不了的占位符进行忽略掉,
        -->
    <context:property-placeholder location="classpath:mail.properties" ignore-unresolvable="true"/>
    <!--配置邮件接口-->
    <bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="${mail.smtp.host}"/>
        <property name="username" value="${mail.smtp.username}"/>
        <property name="password" value="${mail.smtp.password}"/>
        <property name="defaultEncoding" value="${mail.smtp.defaultEncoding}"/>
        <property name="javaMailProperties">
            <props>
                <prop key="mail.smtp.auth">${mail.smtp.auth}</prop>
                <prop key="mail.smtp.timeout">${mail.smtp.timeout}</prop>
            </props>
        </property>
    </bean>

前端代码

这里其实使用 html 也可以, 因为使用的是 ajax 方式, 同时没有使用 jsp 的组件。如果用别的框架也是可以的, 具体参照代码, 发送邮件主要还是后端比较重要, 前端你只需要获取数据比对。

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>后台管理-登陆</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta http-equiv="Access-Control-Allow-Origin" content="*">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <link rel="stylesheet" href="../lib/layui-v2.6.3/css/layui.css" media="all">
    <!--[if lt IE 9]>
    <script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
    <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
    <style>
        body {background-image:url("../images/bg.jpg");height:100%;width:100%;}
        #container{height:100%;width:100%;}
        input:-webkit-autofill {-webkit-box-shadow:inset 0 0 0 1000px #fff;background-color:transparent;}
        .admin-login-background {width:300px;height:300px;position:absolute;left:50%;top:40%;margin-left:-150px;margin-top:-100px;}
        .admin-header {text-align:center;margin-bottom:20px;color:#ffffff;font-weight:bold;font-size:40px}
        .admin-input {border-top-style:none;border-right-style:solid;border-bottom-style:solid;border-left-style:solid;height:50px;width:300px;padding-bottom:0px;}
        .admin-input::-webkit-input-placeholder {color:#a78369}
        .layui-icon-username {color:#a78369 !important;}
        .layui-icon-username:hover {color:#9dadce !important;}
        .layui-icon-password {color:#a78369 !important;}
        .layui-icon-password:hover {color:#9dadce !important;}
        .admin-input-username {border-top-style:solid;border-radius:10px 10px 0 0;}
        .admin-input-verify {border-radius:0 0 10px 10px;}
        .admin-button {margin-top:20px;font-weight:bold;font-size:18px;width:300px;height:50px;border-radius:5px;background-color:#a78369;border:1px solid #d8b29f}
        .admin-icon {margin-left:260px;margin-top:10px;font-size:30px;}
        i {position:absolute;}
        .admin-captcha {position:absolute;margin-left:205px;margin-top:-40px;}
    </style>
    <script src="../js/jquery-2.1.0.min.js" type="text/javascript"></script>
</head>
<body>
<div id="container">
    <div></div>
    <div class="admin-login-background">
        <div class="admin-header">
            <span>layuimini</span>
        </div>
        <form class="layui-form" action="">
<%--            <!-- 附加, 为了封装方便 -->--%>
<%--            <input type="hidden" name="id"  value="2" class="layui-input">--%>

            <div>
                <i class="layui-icon layui-icon-username admin-icon"></i>
                <input type="text" name="username" placeholder="请输入用户名" autocomplete="off" class="layui-input admin-input admin-input-username" value="">
            </div>
            <div>
                <i class="layui-icon layui-icon-password admin-icon"></i>
                <input type="password" name="password" placeholder="请输入密码" autocomplete="off" class="layui-input admin-input" value="">
            </div>
            <div>
                <input type="text" name="verifycode" placeholder="请输入验证码" autocomplete="off" class="layui-input admin-input admin-input-verify" value="">
                <img class="admin-captcha" width="90" height="30" src="${pageContext.request.contextPath}/admin/checkcode">
            </div>
            <button class="layui-btn admin-button" lay-submit="" lay-filter="login">登 陆</button>
        </form>
            <button class="layui-btn admin-button" οnclick="loginWithCode()" >验 证 码 登 陆</button>
    </div>
</div>
<script src="../lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
<script>
    function loginWithCode(){
        //使用验证码登录
        layer.open({
            //layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)
            type:2,
            content:'${pageContext.request.contextPath}/pages/loginwithcode.jsp',
            area: ['30%', '30%'],
            offset: 'auto',
            id: 'add' //设定一个id,防止重复弹出
        });
    }
</script>
<script>
    layui.use(['form'], function () {
        var form = layui.form,
            layer = layui.layer;

        // 登录过期的时候,跳出ifram框架
        if (top.location !== self.location) top.location = self.location;

        // 进行登录操作
        form.on('submit(login)', function (data) {
            data = data.field;
            console.log(data)
            if (data.username == '') {
                layer.msg('用户名不能为空');
                return false;
            }
            if (data.password == '') {
                layer.msg('密码不能为空');
                return false;
            }
            if (data.captcha == '') {
                layer.msg('验证码不能为空');
                return false;
            }

            //发送异步登录请求
            $.ajax({
                url:'${pageContext.request.contextPath}/admin/login',
                type:'POST',
                data: {
                    username: data.username,
                    password: data.password,
                    verifycode: data.verifycode
                },
                success:
                    function (response) {
                        layer.msg(response.msg);
                        console.log(response)
                        //code = 1 代表登录成功
                        if(response.code == "0"){
                            setTimeout(function(){
                                //带参跳转
                                window.location.href = "${pageContext.request.contextPath}/pages/login.jsp"
                            }, 1000);
                            return false;
                        }
                        else if(response.code == "1"){
                            setTimeout(function(){
                                //带参跳转
                                window.location.href = "${pageContext.request.contextPath}/pages/main.jsp?username="
                                    + window.decodeURIComponent(response.data.username) + "&id=" + window.decodeURIComponent(response.data.id);
                            }, 1000);
                        }
                    },
            })
            return false;
        });
    });
</script>
</body>
</html>

loginwithcode.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><!DOCTYPE html>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>layui</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <link rel="stylesheet" href="../css/public.css" media="all">

    <style>
        body {
            background-color: #ffffff;
        }
    </style>
</head>
<body>
    <form class="layui-form layuimini-form"  action="" style="margin-left: -80px">
        <div class="layui-form-item">
            <label class="layui-form-label required">邮箱</label>
            <div class="layui-input-block">
                <input type="text" id="email" name="email"  lay-verify="email" lay-reqtext="邮箱不能为空" placeholder="请输入邮箱(XX@qq/163/gmail.com)" value="" class="layui-input">
            </div>
        </div>

        <div class="layui-form-item">
            <label class="layui-form-label required">验证码</label>
            <div class="layui-input-inline">
                <input type="text" name="code" lay-verify="required" lay-reqtext="验证码不能为空" placeholder="请输入验证码" value="" class="layui-input">
            </div>
            <div class="layui-input-inline">
                <input type="button" class="layui-btn layui-inline" id="send" value="发送验证码" οnclick="sendCode()">
            </div>
        </div>
        <div class="layui-form-item">
            <div class="layui-input-block">
                <button class="layui-btn layui-btn-normal"  lay-submit lay-filter="saveBtn">登录</button>
            </div>
        </div>
    </form>
    <link rel="stylesheet" href="../lib/layui-v2.6.3/css/layui.css" media="all">
    <script src="../lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
    <script src="../js/jquery-2.1.0.min.js" type="text/javascript"></script>
<script>
    function sendCode(){
        //设置按钮不可点击
        document.getElementById("send").disabled = "true";
        document.getElementById("send").className = "layui-btn layui-btn-disabled layui-inline";

        var form = layui.form,
            layer = layui.layer;
        var mail = '';
        mail = $("#email").val();        //获取邮箱
        console.log(typeof mail)
        if (mail.length == 0) {
            alert("邮箱不能为空")
            layer.msg('邮箱不能为空');
            return false;
        }
        $.ajax({
            url:'${pageContext.request.contextPath}/admin/sendCode',
            type: 'post',
            async : false,  //同步请求
            data : {
                mail: mail
            },
            success:function (response) {
                if(response.code == '1'){
                    layer.msg("发送成功", {icon: 6});
                } else{
                    layer.msg("发送失败", {icon: 5});
                }
            }
        })
    }

    layui.use(['form'], function () {
        var form = layui.form,
            layer = layui.layer,
            $ = layui.$;

        //监听提交
        form.on('submit(saveBtn)', function (data) {
            console.log(data)
            $.ajax({
                url:'${pageContext.request.contextPath}/admin/loginWithCode',
                type:'post',
                data : {
                    email: data.field.email,
                    code: data.field.code
                },
                success:function (response) {
                    if(response.code == '1'){
                        layer.msg("登录成功", {icon: 6});
                        setTimeout(function(){
                            var index = parent.layer.getFrameIndex(window.name);//获取窗口索引
                            parent.layer.close(index);      //关闭弹出层
                            //带参跳转
                            parent.window.location.href = "${pageContext.request.contextPath}/pages/main.jsp?username="
                                + window.decodeURIComponent(response.data.username) + "&id=" + window.decodeURIComponent(response.data.id);
                        }, 1000);
                    } else if(response.code == '0'){
                        layer.msg(response.msg, {icon: 5});
                        setTimeout(function(){
                            var index = parent.layer.getFrameIndex(window.name);//获取窗口索引
                            parent.layer.close(index);//关闭弹出层
                            //带参跳转
                            //使用验证码登录
                            parent.layer.open({
                                //layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)
                                type:2,
                                content: "${pageContext.request.contextPath}/pages/signin.jsp?email="+ window.decodeURIComponent($("#email").val()),
                                area: ['40%', '40%'],
                                offset: 'auto',
                                id: 'signin' //设定一个id,防止重复弹出
                            });
                            //parent.window.location.href = ;
                        }, 1000);
                    } else{
                        layer.msg(response.msg, {icon: 5});
                    }
                }
            })

            return false;
        });

    });
</script>


<script src="../lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
</body>
</html>

sign.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!-- 指定字符集 -->
    <meta charset="utf-8">
    <!-- 使用Edge最新的浏览器的渲染方式 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
    width: 默认宽度与设备的宽度相同
    initial-scale: 初始的缩放比,为1:1 -->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <link rel="stylesheet" href="../assets/css/layui.css">
    <script src="../assets/layui.js"></script>
    <script src="../js/jquery-2.1.0.min.js"></script>
    <title>用户注册</title>


    <%--    获取layui属性依赖--%>
    <script>
        layui.use('form', function () {
            var form = layui.form;
            form.render(); //刷新select选择框渲染
        });

        layui.use('element', function(){
            var element = layui.element;
            //一些事件触发
            element.on('tab(demo)', function(data){
                console.log(data);
            });
        });
    </script>

    <%-- 更新登录用户, 获取传递的参数   --%>
    <script type="text/javascript">
        var paramobj = {};
        window.onload = function () {
            //此时parameterURL为:name=张三&age=25
            var parameterURL = location.search.substring(1, location.search.length);
            //此时paramArr为一个数组:["name=张三","age=25"]
            var paramArr = parameterURL.split("&");
            var temp;
            //定义2个变量接收key,value并存到paramobj中
            for (i = 0; i < paramArr.length; i++) {
                temp = paramArr[i].split("=");
                if (temp.length === 1) {
                    paramobj[temp[0]] = "";
                }
                else if(temp.length>1){
                    for (j = 0; j < temp.length; j++) {
                        paramobj[temp[0]] = decodeURIComponent(temp[1]);
                    }
                }
            }
            //此时参数已全部保存至paramobj中,这里显示到div
            var showStr="";
            var email = '';
            var i = 0;
            for (var a in paramobj) {
                if(i === 0)
                    email = paramobj[a];
                showStr += (a + ":" + paramobj[a]);
                i++;
            }
            console.log(showStr, email)
            var input = document.getElementById("email");  //获取input对象
            input.setAttribute("value", email);  //为input对象设置value属性和值
            $("#email").text(email);
            //document.getElementById("mail").innerText = email;
        }
    </script>

    <script>
        layui.use('form', function(){
            var form = layui.form;
            form.on('submit(formDemo)', function(data){
                data = data.field
                console.log(data)
                console.log(data.field)
                console.log(data.form)
                //监听提交
                $.ajax({
                    url : '${pageContext.request.contextPath}/admin/signIn',
                    type : 'post',
                    data : {
                        id: data.id,
                        username: data.username,
                        password: data.password,
                        email: data.email
                    },
                    success : function(response) {
                        if (response.code == '1') {
                            layer.msg("登录成功", {icon: 6});
                            setTimeout(function(){
                                var index = parent.layer.getFrameIndex(window.name);//获取窗口索引
                                parent.layer.close(index);      //关闭弹出层
                                //带参跳转
                                parent.window.location.href = "${pageContext.request.contextPath}/pages/main.jsp?username="
                                    + window.decodeURIComponent(response.data.username) + "&id=" + window.decodeURIComponent(response.data.id);
                            }, 1000);
                        } else {
                            layer.msg("登录失败", {icon: 5});
                        }
                    }
                })
                return false;
            });
        });
    </script>
</head>
<body>
<div class="container" style="width: 100%">
    <div class="layui-card" style="text-align: center;">
        <h3><div class="layui-card-header layui-bg-cyan">用户注册</div></h3>
    </div>

    <form class="layui-form" method="post" action="" style="width: 60%; float:left; margin-left:15% ">
        <input type="hidden" name="id"  value="2" class="layui-input">

        <div class="layui-form-item">
            <label class="layui-form-label">用户名</label>
            <div class="layui-input-block">
                <input type="text" name="username" required  placeholder="请输入用户名" class="layui-input">
            </div>
        </div>

        <div class="layui-form-item">
            <label for="password" class="layui-form-label">密码</label>
            <div class="layui-input-block">
                <input type="text" id="password" name="password"  required  placeholder="请输入密码" class="layui-input">
            </div>
        </div>

        <div class="layui-form-item">
            <label for="email" class="layui-form-label">邮箱</label>
            <div class="layui-input-block">
                <input type="text" id="email" name="email" required class="layui-input" placeholder="请输入邮箱" readonly>
            </div>
        </div>

        <div class="layui-form-item">
            <div class="layui-input-block">
                <button class="layui-btn" lay-submit lay-filter="formDemo">立即提交</button>
                <button type="reset" class="layui-btn layui-btn-primary">重置</button>
            </div>
        </div>
    </form>
</div>
</body>
</html>


后端代码

AdminController

@RequestMapping("/admin")
@Controller
public class AdminController {
    @Autowired
    private AdminService adminService;
    @Autowired
    private  JavaMailSenderImpl javaMailSender;
    @RequestMapping("/signIn")
        @ResponseBody
        public LayuiUtils<Admin> signIn(Admin admin){
            adminService.signIn(admin);
            System.out.println(admin.toString());
            //打印封装数据
            return new LayuiUtils<Admin>("注册成功", admin,1,0);
        }

        @RequestMapping("/sendCode")
        public LayuiUtils<String> sendCode(String mail, HttpServletRequest request) throws MessagingException {
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setSubject("验证码"); // 标题
            String checkcode = getCheckCode();
            //将验证码放入HttpSession中
            request.getSession().setAttribute("codes",checkcode);
            // 内容, 第二个参数为true则以html方式发送, 否则以普通文本发送
            helper.setText("<h1 style='red'>" + checkcode + "</h1>", true);
            //发送附件
            //helper.addAttachment("1.jpg",new File("C:\\Users\\zpk\\Desktop\\loading\\加载-063.gif"));

            helper.setTo(mail); // 收件人
            helper.setFrom("1719XXX051@qq.com"); // 发件人 - 写自己的邮箱名称
            javaMailSender.send(message); // 发送
            //打印封装数据
            return new LayuiUtils<String>("发送成功", null,1,0);
        }

        @RequestMapping("/loginWithCode")
        @ResponseBody
        public LayuiUtils<Admin> loginWithCode(String email, String code, HttpServletRequest request){
            //根据邮箱判断用户是否存在
            Admin admin = adminService.findAdminByEmail(email);

            //从 session 中获取验证码
            HttpSession session = request.getSession();
            String codes = (String)session.getAttribute("codes");

            LayuiUtils<Admin> result;
            //验证码错误
            if(!code.equalsIgnoreCase(codes)){
                System.out.println(codes + code);
                //打印封装数据
                result = new LayuiUtils<Admin>("验证码错误", null,-1,0);
                return result;
            } else if(admin == null){
                result = new LayuiUtils<Admin>("用户不存在,请完成注册!", null,0,0);
                return result;
            } else{
                result = new LayuiUtils<Admin>("登陆成功", admin,1,0);
                return result;
            }
        }
}

OVER~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值