后端使用Spring Boot框架 + 前端VUE 实现滑动模块验证码

八百码 2024-08-22 09:33:10 阅读 99

   在现在常用的登录验证码方式有很多种,但是都不可避免被攻击,但是有很多方式可以防止被攻击,从而进行维护。

  现在我就讲解一下滑动块验证码的实现方式:

这个是前端代码,我使用的是vue,在使用的时候注意:

注意几个关键点:

使用Vue的data函数来存储组件的状态,如isDraggingsliderPosition等。使用Vue的mounted生命周期钩子来获取容器和滑块的宽度。使用Vue的ref属性来方便地访问DOM元素。在模板中使用:style绑定来动态设置滑块的left样式。监听mousedownmousemovemouseup(以及mouseleave以防鼠标移出窗口时未释放)事件来处理拖动逻辑。使用async/await来处理异步的API请求。

<template>

<div class="captcha-container" @mouseup="handleMouseUp" @mouseleave="handleMouseUp">

<div class="slider" :style="{ left: sliderPosition + 'px' }" @mousedown="handleMouseDown" @mousemove="handleMouseMove" @mouseleave="handleMouseUp">滑动</div>

</div>

</template>

<script>

export default { -- -->

data() {

return {

isDragging: false,

startX: 0,

sliderPosition: 0,

containerWidth: 0,

sliderWidth: 50,

};

},

mounted() {

this.containerWidth = this.$el.offsetWidth;

this.sliderWidth = this.$refs.slider.offsetWidth;

},

methods: {

handleMouseDown(event) {

this.isDragging = true;

this.startX = event.clientX - this.$refs.slider.offsetLeft;

},

handleMouseMove(event) {

if (this.isDragging) {

const newX = event.clientX - this.startX;

const maxX = this.containerWidth - this.sliderWidth;

this.sliderPosition = Math.max(0, Math.min(newX, maxX));

}

},

handleMouseUp() {

if (this.isDragging) {

this.isDragging = false;

this.verifyCaptcha(this.sliderPosition);

}

},

async verifyCaptcha(position) {

try {

const response = await fetch('后端验证接口的URL', {

method: 'POST',

headers: {

'Content-Type': 'application/json',

},

body: JSON.stringify({ sliderPosition: position }),

});

const data = await response.json();

if (data.success) {

alert('验证通过!');

// 自定义需求

} else {

alert('验证失败,请重新拖动滑块!');

this.sliderPosition = 0;

}

} catch (error) {

console.error('验证失败:', error);

alert('验证过程中发生错误,请重试!');

}

},

},

};

</script>

<style scoped>

.captcha-container {

position: relative;

width: 300px;

height: 150px;

background-image: url('可以根据需求放置背景图片的路径');

background-size: cover;

overflow: hidden;

cursor: pointer;

}

.slider {

position: absolute;

width: 50px;

height: 50px;

background-color: #337ab7;

color: #fff;

text-align: center;

line-height: 50px;

cursor: pointer;

user-select: none; /* 防止拖动时选中文字 */

}

</style>

后端我使用的java代码实现,

前端Vue组件的修改

确保前端Vue组件中的fetch请求URL与后端控制器中的/verify-captcha相匹配。

注意事项

安全性:在实际应用中,预期的滑块位置(expectedPosition)应该是动态生成的,并且只能被一次验证使用(例如,存储在数据库中并与用户会话相关联)。验证逻辑:上面的示例使用了简单的数值比较。在实际应用中,你可能需要实现更复杂的验证逻辑,比如考虑用户拖动滑块的速度、加速度等。错误处理:在后端控制器中添加适当的错误处理逻辑,以便在验证失败或发生其他错误时向前端返回有用的错误信息。CORS(跨源资源共享):如果你的前端和后端部署在不同的域上,你需要在后端添加CORS支持,以便前端能够成功向后端发送请求。

import org.springframework.web.bind.annotation.PostMapping;  

import org.springframework.web.bind.annotation.RequestBody;  

import org.springframework.web.bind.annotation.RestController;  

  

@RestController  

public class CaptchaController {  

  

    // 假设的验证码验证逻辑(实际中可能需要更复杂的逻辑)  

    private int expectedPosition = 100; // 假设预期的滑块位置是100  

  

    @PostMapping("/verify-captcha")  

    public ResponseEntity<CaptchaResponse> verifyCaptcha(@RequestBody CaptchaRequest request) {  

        // 验证滑块位置  

        boolean isValid = request.getSliderPosition() == expectedPosition;  

  

        // 这里只是简单示例,实际中可能需要从数据库或缓存中获取expectedPosition  

  

        CaptchaResponse response = new CaptchaResponse();  

        response.setSuccess(isValid);  

  

        return ResponseEntity.ok(response);  

    }  

  

    // 简单的请求和响应DTO  

    static class CaptchaRequest {  

        private int sliderPosition;  

  

        // Getters and Setters  

        public int getSliderPosition() {  

            return sliderPosition;  

        }  

  

        public void setSliderPosition(int sliderPosition) {  

            this.sliderPosition = sliderPosition;  

        }  

    }  

  

    static class CaptchaResponse {  

        private boolean success;  

  

        // Getters and Setters  

        public boolean isSuccess() {  

            return success;  

        }  

  

        public void setSuccess(boolean success) {  

            this.success = success;  

        }  

    }  

}

  



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。