layui如何实现登陆界面验证码

发布时间:2021-11-30 10:51:05 作者:iii
来源:亿速云 阅读:1099
# layui如何实现登录界面验证码

## 一、验证码功能概述

验证码(CAPTCHA)是"Completely Automated Public Turing test to tell Computers and Humans Apart"的缩写,用于区分人类用户和自动化程序。在登录界面中加入验证码可以有效防止暴力破解和恶意登录攻击。

### 1.1 验证码的主要作用
- 防止暴力破解:增加自动化尝试的难度
- 提升安全性:阻挡大部分自动化攻击脚本
- 区分人机:确保操作者是真实用户
- 减轻服务器压力:减少无效请求

### 1.2 layui实现验证码的优势
- 轻量级框架,集成简单
- 内置丰富的UI组件
- 良好的浏览器兼容性
- 简洁的API设计

## 二、基础环境准备

### 2.1 layui引入
```html
<!-- 引入layui核心文件 -->
<link rel="stylesheet" href="//unpkg.com/layui@2.6.8/dist/css/layui.css">
<script src="//unpkg.com/layui@2.6.8/dist/layui.js"></script>

2.2 基础HTML结构

<div class="layui-container">
  <div class="layui-row">
    <div class="layui-col-md4 layui-col-md-offset4">
      <form class="layui-form" action="">
        <div class="layui-form-item">
          <label class="layui-form-label">用户名</label>
          <div class="layui-input-block">
            <input type="text" name="username" required lay-verify="required" placeholder="请输入用户名" autocomplete="off" class="layui-input">
          </div>
        </div>
        
        <div class="layui-form-item">
          <label class="layui-form-label">密码</label>
          <div class="layui-input-block">
            <input type="password" name="password" required lay-verify="required" placeholder="请输入密码" autocomplete="off" class="layui-input">
          </div>
        </div>
        
        <!-- 验证码区域 -->
        <div class="layui-form-item">
          <label class="layui-form-label">验证码</label>
          <div class="layui-input-inline">
            <input type="text" name="captcha" required lay-verify="required" placeholder="请输入验证码" autocomplete="off" class="layui-input">
          </div>
          <div class="layui-form-mid layui-word-aux">
            <img id="captchaImg" src="/captcha" onclick="refreshCaptcha()" style="cursor:pointer;">
          </div>
        </div>
        
        <div class="layui-form-item">
          <div class="layui-input-block">
            <button class="layui-btn" lay-submit lay-filter="login">立即登录</button>
            <button type="reset" class="layui-btn layui-btn-primary">重置</button>
          </div>
        </div>
      </form>
    </div>
  </div>
</div>

三、服务端验证码生成(Java示例)

3.1 使用Kaptcha库

<!-- Maven依赖 -->
<dependency>
  <groupId>com.github.penggle</groupId>
  <artifactId>kaptcha</artifactId>
  <version>2.3.2</version>
</dependency>

3.2 Spring Boot配置类

@Configuration
public class KaptchaConfig {
    
    @Bean
    public Producer kaptchaProducer() {
        Properties properties = new Properties();
        properties.setProperty("kaptcha.image.width", "120");
        properties.setProperty("kaptcha.image.height", "40");
        properties.setProperty("kaptcha.textproducer.font.size", "30");
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
        
        Config config = new Config(properties);
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

3.3 控制器实现

@RestController
@RequestMapping("/captcha")
public class CaptchaController {
    
    @Autowired
    private Producer kaptchaProducer;
    
    @GetMapping
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 禁止缓存
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/jpeg");
        
        // 生成验证码文本
        String capText = kaptchaProducer.createText();
        // 存入session
        request.getSession().setAttribute("captcha", capText);
        
        // 生成图片
        BufferedImage bi = kaptchaProducer.createImage(capText);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
    }
}

四、前端交互实现

4.1 验证码刷新功能

// 刷新验证码
function refreshCaptcha() {
    document.getElementById('captchaImg').src = '/captcha?t=' + new Date().getTime();
}

4.2 layui表单验证

layui.use(['form', 'layer'], function(){
    var form = layui.form;
    var layer = layui.layer;
    
    // 表单提交
    form.on('submit(login)', function(data){
        // 验证验证码
        $.ajax({
            url: '/verifyCaptcha',
            type: 'POST',
            data: {captcha: data.field.captcha},
            success: function(res) {
                if(res.success) {
                    // 验证码正确,提交登录表单
                    $.post('/login', data.field, function(result) {
                        if(result.success) {
                            layer.msg('登录成功', {icon: 1});
                            setTimeout(function(){
                                window.location.href = '/index';
                            }, 1000);
                        } else {
                            layer.msg(result.msg || '登录失败', {icon: 2});
                            refreshCaptcha();
                        }
                    });
                } else {
                    layer.msg('验证码错误', {icon: 2});
                    refreshCaptcha();
                }
            }
        });
        return false;
    });
});

4.3 验证码校验服务端

@PostMapping("/verifyCaptcha")
public Map<String, Object> verifyCaptcha(@RequestParam String captcha, HttpSession session) {
    Map<String, Object> result = new HashMap<>();
    String sessionCaptcha = (String) session.getAttribute("captcha");
    if (captcha == null || !captcha.equalsIgnoreCase(sessionCaptcha)) {
        result.put("success", false);
        result.put("msg", "验证码错误");
    } else {
        result.put("success", true);
        // 验证成功后移除session中的验证码
        session.removeAttribute("captcha");
    }
    return result;
}

五、高级功能扩展

5.1 滑动验证码集成

引入滑块验证组件

<script src="//unpkg.com/@alex_xu/slide-verify/dist/slide-verify.js"></script>
<link rel="stylesheet" href="//unpkg.com/@alex_xu/slide-verify/dist/slide-verify.css">

实现代码

var slideVerify = new SlideVerify({
    elementId: 'slider',  // 容器ID
    mode: 'fixed',        // 模式:fixed固定模式,pop弹出模式
    width: 350,           // 宽度
    height: 200,          // 高度
    sliderText: '向右滑动', // 提示文字
    success: function() {
        // 验证成功回调
        $('#hiddenCaptcha').val('verified');
    }
});

5.2 短信验证码集成

前端实现

// 发送短信验证码
function sendSmsCode() {
    var phone = $('#phone').val();
    if(!phone) {
        layer.msg('请输入手机号', {icon: 2});
        return;
    }
    
    $.post('/sendSms', {phone: phone}, function(res) {
        if(res.success) {
            layer.msg('验证码已发送', {icon: 1});
            startCountdown();
        } else {
            layer.msg(res.msg, {icon: 2});
        }
    });
}

// 倒计时功能
function startCountdown() {
    var countdown = 60;
    var $btn = $('#smsBtn');
    $btn.attr('disabled', true);
    
    var timer = setInterval(function() {
        if(countdown <= 0) {
            clearInterval(timer);
            $btn.text('获取验证码').attr('disabled', false);
        } else {
            $btn.text(countdown + '秒后重试');
            countdown--;
        }
    }, 1000);
}

六、安全优化建议

6.1 验证码安全策略

  1. 时效性控制:设置验证码过期时间(通常2-5分钟)
  2. 使用次数限制:每个验证码仅允许使用一次
  3. 复杂度控制:避免纯数字,建议字母数字混合
  4. 大小写敏感:建议不区分大小写,提升用户体验
  5. 频率限制:同一IP/用户限制验证码获取频率

6.2 防破解措施

  1. 图形干扰:添加干扰线、噪点、扭曲等
  2. 动态效果:使用动态验证码(如GIF)
  3. 行为验证:结合滑动、点击等行为验证
  4. 二次验证:高危操作使用多因素验证
  5. 日志监控:记录验证失败日志,分析异常行为

七、常见问题解决方案

7.1 验证码不显示

7.2 验证码刷新失效

// 确保每次请求URL不同
function refreshCaptcha() {
    var captchaImg = document.getElementById('captchaImg');
    captchaImg.src = '/captcha?t=' + Date.now();
}

7.3 移动端适配问题

/* 响应式调整 */
@media screen and (max-width: 768px) {
    .layui-form-item .layui-input-inline {
        width: 100%;
    }
    #captchaImg {
        width: 100%;
        height: auto;
    }
}

八、完整示例代码

8.1 前端完整代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>登录验证码示例</title>
    <link rel="stylesheet" href="//unpkg.com/layui@2.6.8/dist/css/layui.css">
    <style>
        .login-container {
            margin-top: 100px;
        }
        .captcha-img {
            height: 38px;
            vertical-align: middle;
        }
    </style>
</head>
<body>
<div class="layui-container login-container">
    <div class="layui-row">
        <div class="layui-col-md4 layui-col-md-offset4">
            <form class="layui-form" action="">
                <div class="layui-form-item">
                    <label class="layui-form-label">用户名</label>
                    <div class="layui-input-block">
                        <input type="text" name="username" required lay-verify="required" placeholder="请输入用户名" autocomplete="off" class="layui-input">
                    </div>
                </div>
                
                <div class="layui-form-item">
                    <label class="layui-form-label">密码</label>
                    <div class="layui-input-block">
                        <input type="password" name="password" required lay-verify="required" placeholder="请输入密码" autocomplete="off" class="layui-input">
                    </div>
                </div>
                
                <div class="layui-form-item">
                    <label class="layui-form-label">验证码</label>
                    <div class="layui-input-inline">
                        <input type="text" name="captcha" required lay-verify="required" placeholder="请输入验证码" autocomplete="off" class="layui-input">
                    </div>
                    <div class="layui-form-mid">
                        <img id="captchaImg" src="/captcha" onclick="refreshCaptcha()" class="captcha-img" title="点击刷新">
                    </div>
                </div>
                
                <div class="layui-form-item">
                    <div class="layui-input-block">
                        <button class="layui-btn" lay-submit lay-filter="login">登录</button>
                        <button type="reset" class="layui-btn layui-btn-primary">重置</button>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>

<script src="//unpkg.com/layui@2.6.8/dist/layui.js"></script>
<script src="//unpkg.com/jquery@3.6.0/dist/jquery.min.js"></script>
<script>
layui.use(['form', 'layer'], function(){
    var form = layui.form;
    var layer = layui.layer;
    
    // 刷新验证码
    window.refreshCaptcha = function() {
        $('#captchaImg').attr('src', '/captcha?t=' + Date.now());
    }
    
    // 表单提交
    form.on('submit(login)', function(data){
        $.ajax({
            url: '/verifyCaptcha',
            type: 'POST',
            data: {captcha: data.field.captcha},
            success: function(res) {
                if(res.success) {
                    // 验证码正确,提交登录
                    $.post('/login', data.field, function(result) {
                        if(result.success) {
                            layer.msg('登录成功', {icon: 1});
                            setTimeout(function(){
                                window.location.href = '/index';
                            }, 1000);
                        } else {
                            layer.msg(result.msg || '登录失败', {icon: 2});
                            refreshCaptcha();
                        }
                    });
                } else {
                    layer.msg('验证码错误', {icon: 2});
                    refreshCaptcha();
                }
            }
        });
        return false;
    });
});
</script>
</body>
</html>

九、总结

本文详细介绍了在layui框架中实现登录验证码的完整方案,包括: 1. 基础图形验证码的实现 2. 前后端交互流程 3. 安全优化策略 4. 常见问题解决方案 5. 高级功能扩展思路

通过合理的验证码设计,可以显著提升系统安全性,同时layui的简洁API使得前端实现变得非常便捷。开发者可以根据实际需求选择适合的验证码类型,并参考本文提供的优化建议构建更安全的登录系统。 “`

推荐阅读:
  1. qq登陆界面
  2. layui发送手机验证码

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

layui

上一篇:C#将Excel转为PDF时怎么自定义表格纸张大小

下一篇:C/C++ Qt TreeWidget单层树形组件怎么应用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》