前端验证码(java 登录滑动验证码功能实现)

前端验证码(java 登录滑动验证码功能实现)
java 登录滑动验证码功能实现
  1. spring boot使用版本
    org.springframework.boot    spring-boot-starter-parent    3.2.0  

2.pom.xml依赖包

  <!-- Spring Web -->          org.springframework.boot      spring-boot-starter-web        <!-- 验证码框架导入 -->          cloud.tianai.captcha      tianai-captcha-springboot-starter      1.5.5        <!-- 引用web前端框架 -->          org.springframework.boot      spring-boot-starter-thymeleaf              org.projectlombok      lombok      true    

3.application.yml验证码配置

前端验证码(java 登录滑动验证码功能实现)

# 行为验证码配置, 详细请看 cloud.tianai.captcha.autoconfiguration.ImageCaptchaProperties 类captcha:  # 如果项目中使用到了redis,滑块验证码会自动把验证码数据存到redis中, 这里配置redis的key的前缀,默认是captcha:slider  prefix: captcha  # 验证码过期时间,默认是2分钟,单位毫秒, 可以根据自身业务进行调整  expire:    # 默认缓存时间 2分钟    default: 10000    # 针对 点选验证码 过期时间设置为 2分钟, 因为点选验证码验证比较慢,把过期时间调整大一些    WORD_IMAGE_CLICK: 20000  # 使用加载系统自带的资源, 默认是 false(这里系统的默认资源包含 滑动验证码模板/旋转验证码模板,如果想使用系统的模板,这里设置为true)  init-default-resource: true  # 缓存控制, 默认为false不开启  local-cache-enabled: false  # 缓存开启后,验证码会提前缓存一些生成好的验证数据, 默认是20  local-cache-size: 20  # 缓存开启后,缓存拉取失败后等待时间 默认是 5秒钟  local-cache-wait-time: 5000  # 缓存开启后,缓存检查间隔 默认是2秒钟  local-cache-period: 2000  # 缓存开启后,忽略的字段,默认是 ""(不忽略任何字段)  local-cache-ignored-cache-fields: ""  # 配置字体包,供文字点选验证码使用,可以配置多个,不配置使用默认的字体  font-path:    - classpath:font/SimHei.ttf  secondary:    # 二次验证, 默认false 不开启    enabled: false    # 二次验证过期时间, 默认 2分钟    expire: 120000    # 二次验证缓存key前缀,默认是 captcha:secondary    keyPrefix: "captcha:secondary"

4.配置验证码资源存储器

import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;import cloud.tianai.captcha.resource.ResourceStore;import cloud.tianai.captcha.resource.impl.LocalMemoryResourceStore;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import cloud.tianai.captcha.resource.common.model.dto.Resource;@Configurationpublic class CaptchaResourceConfiguration {    /**     * 配置验证码资源存储器     * @return ResourceStore     */    @Bean    public ResourceStore resourceStore() {        // 使用简单的本地内存存储器,实际项目中可以使用数据库等存储        LocalMemoryResourceStore resourceStore = new LocalMemoryResourceStore();        // 配置背景图        // arg1: 验证码类型(SLIDER、ROTATE、CONCAT、WORD_IMAGE_CLICK)        // arg2: Resource对象,包含: 资源类型(calsspath、file、url)、文件路径、tag标签        resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/a.jpg", "default"));        resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/b.jpg", "default"));        resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/c.jpg", "default"));        resourceStore.addResource(CaptchaTypeConstant.ROTATE, new Resource("classpath", "bgimages/48.jpg", "default"));        resourceStore.addResource(CaptchaTypeConstant.CONCAT, new Resource("classpath", "bgimages/48.jpg", "default"));        resourceStore.addResource(CaptchaTypeConstant.WORD_IMAGE_CLICK, new Resource("classpath", "bgimages/c.jpg", "default"));        return resourceStore;    }}

5.验证码controller类

import cloud.tianai.captcha.application.ImageCaptchaApplication;import cloud.tianai.captcha.application.vo.ImageCaptchaVO;import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;import cloud.tianai.captcha.common.response.ApiResponse;import cloud.tianai.captcha.generator.common.model.dto.GenerateParam;import cloud.tianai.captcha.spring.plugins.secondary.SecondaryVerificationApplication;import cloud.tianai.captcha.validator.common.model.dto.ImageCaptchaTrack;import jakarta.servlet.http.HttpServletRequest;import lombok.Data;import org.apache.commons.lang3.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import java.util.Collections;import java.util.concurrent.ThreadLocalRandom;@RestControllerpublic class CaptchaController {    @Autowired    private ImageCaptchaApplication imageCaptchaApplication;    @RequestMapping("/gen")    @ResponseBody    public ApiResponse genCaptcha(HttpServletRequest request, @RequestParam(value = "type", required = false)String type) {        if (StringUtils.isBlank(type)) {            type = CaptchaTypeConstant.SLIDER;        }        if ("RANDOM".equals(type)) {            int i = ThreadLocalRandom.current().nextInt(0, 4);            if (i == 0) {                type = CaptchaTypeConstant.SLIDER;            } else if (i == 1) {                type = CaptchaTypeConstant.CONCAT;            } else if (i == 2) {                type = CaptchaTypeConstant.ROTATE;            } else{                type = CaptchaTypeConstant.WORD_IMAGE_CLICK;            }        }        GenerateParam generateParam = new GenerateParam();        // 要生成的验证码类型        generateParam.setType(type);        ApiResponse response = imageCaptchaApplication.generateCaptcha(generateParam);        return response;    }    @PostMapping("/check")    @ResponseBody    public ApiResponse<!--?--> checkCaptcha(@RequestBody Data data,                                       HttpServletRequest request) {        ApiResponse<!--?--> response = imageCaptchaApplication.matching(data.getId(), data.getData());        if (response.isSuccess()) {            return ApiResponse.ofSuccess(Collections.singletonMap("id", data.getId()));        }        return response;    }    @lombok.Data    public static class Data {        private String  id;        private ImageCaptchaTrack data;    }    /**     * 二次验证,一般用于机器内部调用,这里为了方便测试     * @param id id     * @return boolean     */    @GetMapping("/check2")    @ResponseBody    public boolean check2Captcha(@RequestParam("id") String id) {        // 如果开启了二次验证        if (imageCaptchaApplication instanceof SecondaryVerificationApplication) {            return ((SecondaryVerificationApplication) imageCaptchaApplication).secondaryVerification(id);        }        return false;    }}

6.登录类

import cloud.tianai.captcha.application.ImageCaptchaApplication;import cloud.tianai.captcha.spring.plugins.secondary.SecondaryVerificationApplication;import jakarta.servlet.http.HttpSession;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.*;import java.util.HashMap;import java.util.Map;@Controller//@CrossOrigin(origins = "*")public class LoginController {    @Autowired    private ImageCaptchaApplication imageCaptchaApplication;    // 模拟账号密码    private static final String USERNAME = "admin";    private static final String PASSWORD = "123456";    /**     * 登录页面     * @param model     * @return     */    @RequestMapping(value="/login",method = RequestMethod.GET)    public String getLogin(Model model){        return "login";    }    /**     * 欢迎页面     * @param model     * @return     */    @RequestMapping(value="/home",method = RequestMethod.GET)    public String getHome(Model model){        return "home";    }    /**     * 3. 登录接口(必须先通过滑块验证)     */    @PostMapping("/login")    @ResponseBody    public Map login(            @RequestParam String username,            @RequestParam String password,            @RequestParam String token, // 图片验证码token            HttpSession session) {        Map result = new HashMap<>();        result.put("success", false);        // 1. 校验滑块是否验证        // 如果开启了二次验证        if (imageCaptchaApplication instanceof SecondaryVerificationApplication) {            boolean codeSuccess=((SecondaryVerificationApplication) imageCaptchaApplication).secondaryVerification(token);            if (!codeSuccess){                result.put("msg", "请先完成滑动验证!");                return result;            }        }        // 2. 非空校验        if (username.isEmpty() || password.isEmpty()) {            result.put("msg", "请输入用户名/密码");            return result;        }        // 3. 账号密码校验        if (USERNAME.equals(username) && PASSWORD.equals(password)) {            result.put("success", true);            result.put("msg", "登录成功");        } else {            result.put("msg", "用户名或密码错误");        }        return result;    }    @PostMapping("/logout")    @ResponseBody    public Map logout(HttpSession session) {        session.invalidate(); // 清空所有Session        Map result = new HashMap<>();        result.put("success", true);        result.put("msg", "退出成功");        return result;    }}

7.前端登录login.html

    滑动验证码登录            [xss_clean][xss_clean]    [xss_clean][xss_clean][xss_clean]    function login(token) {        let username = document.getElementById("username").value;        let password = document.getElementById("password").value;        fetch("/login", {            method: "POST",            headers: { "Content-Type": "application/x-www-form-urlencoded" },            body: `username=${username}&password=${password}&token=${token}`        })            .then(res => res.json())            .then(data => {                if (data.success) {                    location.href = "/home?username="+username;                }else{                    alert(data.msg);                }            });    }    // 4. 登录提交    function submitLogin() {        const captchaConfig = {            // 生成接口 (必选项,必须配置, 要符合tianai-captcha默认验证码生成接口规范)            // 正确返回的数据结构: {code:200, data:{}}            // 异常返回的数据结构: {code:500, msg:'xxx'}            requestCaptchaDataUrl: "/gen?type=SLIDER",            // 验证接口            validCaptchaUrl: "/check",            // 验证码绑定的div块            bindEl: "#captcha-box",            // 验证成功回调函数(必选项,必须配置)            validSuccess: (res, c, t) => {                console.log("验证码验证成功回调...");                // 销毁验证码组件                t.destroyWindow();                // 调用具体的业务方法                login(res.data.token);            },            // 验证失败的回调函数(可忽略,如果不自定义 validFail 方法时,会使用默认的)            validFail: (res, c, t) => {                console.log("验证码验证失败回调...");                // 验证失败后重新拉取验证码                t.reloadCaptcha();            },            // 刷新按钮回调事件            btnRefreshFun: (el, tac) => {                console.log("刷新按钮触发事件...");                tac.reloadCaptcha();            },            // 关闭按钮回调事件            btnCloseFun: (el, tac) => {                console.log("关闭按钮触发事件...");                tac.destroyWindow();            }        };        // 一些样式配置, 可不传        const style = {            // logoUrl: "..."        };        // 创建 TAC 启动验证码服务        new TAC(captchaConfig, style).init();    }[xss_clean]

8.效果图

9.源码下载

https://gitee.com/rang/silder-validate-demo.git

文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有

相关阅读