效果

话不多说,点击查看 实现的效果

  • 前端

  • 后台

核心流程分析

  • 服务端随机生成滑块图片和带滑块抠图的背景图片,并保存滑块抠图的坐标位置

  • 前端实现滑动交互,将抠图拼在抠图阴影之上,获取到用户滑动轨迹

  • 前端将滑动轨迹上报到服务端,服务端匹配是否与抠图坐标在允许的误差范围(这里单纯校验用户滑动距离是最基本的校验,出于更高的安全考虑,
    还会考虑用户滑动的整个轨迹,用户在当前页面的访问行为等。这些可以很复杂,甚至借助到用户行为数据分析模型,
    最终的目标都是增加非法的模拟和绕过的难度。)

  • 滑动轨迹验证通过,服务端生成ticket票据和验证码随机数jsonp方式给到前端

  • 前端将验证通过的ticket和随机数上报给业务服务端

  • 业务服务端调用API方式到验证码服务器校验ticket的合法性

本文重点讲的核心是滑动验证码中滑块和阴影背景图的处理生成,滑块的形状和抠图坐标位置都是随机
生成的,这样可以增加暴力破解的难度。

话不多说,直接上关键实现代码

/*** 生成随机滑块形状* * 0 透明像素* 1 滑块像素* 2 阴影像素** @return*/private static int[][] getBlockData() {int[][] data = new int[CUT_WIDTH][CUT_HEIGHT];//(x-a)²+(y-b)²=r²//x中心位置左右5像素随机double x1 = RECTANGLE_PADDING + (CUT_WIDTH - 2 * RECTANGLE_PADDING) / 2.0 - 5 + RandomUtil.randomInt(0, 11);//y 矩形上边界半径-1像素移动double y1_top = RECTANGLE_PADDING - RandomUtil.randomInt(0, 3);double y1_bottom = CUT_HEIGHT - RECTANGLE_PADDING + RandomUtil.randomInt(0, 3);double y1 = RandomUtil.randomInt(0, 2) == 1 ? y1_top : y1_bottom;double x2_right = CUT_WIDTH - RECTANGLE_PADDING - circleR + RandomUtil.randomInt(0, 2 * circleR - 3);double x2_left = RECTANGLE_PADDING + circleR - 2 - RandomUtil.randomInt(0, 2 * circleR - 3);double x2 = RandomUtil.randomInt(0, 2) == 1 ? x2_right : x2_left;double y2 = RECTANGLE_PADDING + (CUT_HEIGHT - 2 * RECTANGLE_PADDING) / 2.0 - 5 + RandomUtil.randomInt(0, 11);double po = circleR * circleR;for (int i = 0; i < CUT_WIDTH; i++) {for (int j = 0; j < CUT_HEIGHT; j++) {//矩形区域boolean fill;if ((i >= RECTANGLE_PADDING && i < CUT_WIDTH - RECTANGLE_PADDING)&& (j >= RECTANGLE_PADDING && j < CUT_HEIGHT - RECTANGLE_PADDING)) {data[i][j] = 1;fill = true;} else {data[i][j] = 0;fill = false;}//凸出区域double d3 = Math.pow(i - x1, 2) + Math.pow(j - y1, 2);if (d3 < po) {data[i][j] = 1;} else {if (!fill) {data[i][j] = 0;}}//凹进区域double d4 = Math.pow(i - x2, 2) + Math.pow(j - y2, 2);if (d4 < po) {data[i][j] = 0;}}}//边界阴影for (int i = 0; i < CUT_WIDTH; i++) {for (int j = 0; j < CUT_HEIGHT; j++) {//四个正方形边角处理for (int k = 1; k <= SLIDER_IMG_OUT_PADDING; k++) {//左上、左下if (i >= RECTANGLE_PADDING - k && i < RECTANGLE_PADDING&& ((j >= RECTANGLE_PADDING - k && j < RECTANGLE_PADDING)|| (j >= CUT_HEIGHT - RECTANGLE_PADDING - k && j < CUT_HEIGHT - RECTANGLE_PADDING + 1))) {data[i][j] = 2;}//右上、右下if (i >= CUT_WIDTH - RECTANGLE_PADDING + k - 1 && i < CUT_WIDTH - RECTANGLE_PADDING + 1) {for (int n = 1; n <= SLIDER_IMG_OUT_PADDING; n++) {if (((j >= RECTANGLE_PADDING - n && j < RECTANGLE_PADDING)|| (j >= CUT_HEIGHT - RECTANGLE_PADDING - n && j <= CUT_HEIGHT - RECTANGLE_PADDING ))) {data[i][j] = 2;}}}}if (data[i][j] == 1 && j - SLIDER_IMG_OUT_PADDING > 0 && data[i][j - SLIDER_IMG_OUT_PADDING] == 0) {data[i][j - SLIDER_IMG_OUT_PADDING] = 2;}if (data[i][j] == 1 && j + SLIDER_IMG_OUT_PADDING > 0 && j + SLIDER_IMG_OUT_PADDING < CUT_HEIGHT && data[i][j + SLIDER_IMG_OUT_PADDING] == 0) {data[i][j + SLIDER_IMG_OUT_PADDING] = 2;}if (data[i][j] == 1 && i - SLIDER_IMG_OUT_PADDING > 0 && data[i - SLIDER_IMG_OUT_PADDING][j] == 0) {data[i - SLIDER_IMG_OUT_PADDING][j] = 2;}if (data[i][j] == 1 && i + SLIDER_IMG_OUT_PADDING > 0 && i + SLIDER_IMG_OUT_PADDING < CUT_WIDTH && data[i + SLIDER_IMG_OUT_PADDING][j] == 0) {data[i + SLIDER_IMG_OUT_PADDING][j] = 2;}}}return data;}

运行效果

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 1 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
/*** 裁剪区块** @param oriImage    原图* @param targetImage 裁剪图* @param blockImage  滑块* @param x           裁剪点x* @param y           裁剪点y*/private static void cutImg(BufferedImage oriImage, BufferedImage targetImage, int[][] blockImage, int x, int y) {for (int i = 0; i < CUT_WIDTH; i++) {for (int j = 0; j < CUT_HEIGHT; j++) {int _x = x + i;int _y = y + j;int rgb = blockImage[i][j];// 原图中对应位置变色处理if (rgb == 1) {int rgb_ori = oriImage.getRGB(_x, _y);//抠图上复制对应颜色值targetImage.setRGB(_x, _y, rgb_ori);//原图对应位置颜色变化oriImage.setRGB(_x, _y, Color.LIGHT_GRAY.getRGB());} else if (rgb == 2) {targetImage.setRGB(_x, _y, Color.WHITE.getRGB());oriImage.setRGB(_x, _y, Color.GRAY.getRGB());}}}}

通过上述处理后对滑块图片、背景图片、抠图坐标在服务端存储。

其他

  • 服务端对图片上传时要做一定大小,比例的限制,尽可能在图片不失真的情况下图片大小可控,这样
    可以提高前端的加载速度,当然最终图片都是通过CDN加速的,java有一个比较好的开源工具可以实现这些操作
    具体的可以自行去查看 thumbnailator

  • 前端跟服务端上报参数以及验证参数都是通过AES对称加密,当然加密的偏移量和密钥都是跟随验证码随机生成的

  • 裁剪的滑块验证码库都会通过定时器定时对图片动态更新,更新频率可自行控制

  • 为增加获取图片验证码的QPS以及安全性,客户端刷新验证码都是随机从验证码库中获取一组,并且生成
    随机数存放在redis集群中,并设置1分钟的过期

Java实现拖动图片验证处理相关推荐

  1. java 拖动验证码实现_java实现拖动图片验证码

    思路是,对原图产生两张图片,一张是底图,被抠掉一部分的图片,另外一张是移动图,被抠出的来部分 只写了后台怎么生成拖动验证码的两个图片,前端的还没写,待续.以下是后台的代码 class="ja ...

  2. Android深入浅出系列之实例应用—简单的手指拖动图片,图片滑来滑去显示应用Gallery和BaseAdapter以及ImageView的使用...

    前言 我们现在在随便一个手机上用手指在屏幕上滑来滑都可以去拖动图片,其实在Android里这很简单,下面我就给大家具体讲解一下. 思路   我们首先需要Gallery这个对象,俗称画廊对象,大家都知道 ...

  3. 乱序图片 极验_极验验证吴渊:传统图片验证方式已经无效了!

    吴渊,极意网络CEO 黑五月频发的宕机门告诉我们:数据安全,所有创业者都应该关注! 让我们来听听IDG资本的两位投资人大佬的深刻分析,以及5家创业公司CEO/CTO大拿的深切呼吁吧!--这里不止有干货 ...

  4. Java中使用图片验证码 --菜鸟小回

    Java中使用图片验证码 一.第一种方式 工具类 @WebServlet("/BufferImage") public class BufferImage extends Http ...

  5. java -- cropper裁剪图片并base64上传 移动端简单示例

    前言 cropper是一款使用简单且功能强大的图片剪裁jQuery插件.该图片剪裁插件支持图片放大缩小,支持图片旋转,支持触摸屏设备,支持canvas,并且支持跨浏览器使用. cropper有两种方式 ...

  6. 登录图片验证(vue3)

    登录图片验证(vue3) 我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客: html布局 ,分为上下两个区域 ...

  7. SSM框架下实现验证码图片验证功能(源码)

    SSM框架下实现验证码图片验证功能 背景图片资源路径 https://download.csdn.net/download/hero_qhz/10322064 一.首先,在pom里面加上需要用的资源j ...

  8. JavaScript实现拖动滑块验证(方法已封装)

    前提 之前写了一篇博文,题目是<JavaScript实现拖动滑块验证>,里面都是用最简单的方式实现的.后来,群里大神推荐了一款unlock.js插件,称作幻灯片解锁插件.在这里附上它的gi ...

  9. 用鼠标拖动图片的JS代码

    代码简介: 用鼠标拖动一个图片移动,就像拖动一个层一样,这是一个JS拖动类代码,你可以无限制的增加图片,代码复用率比较高. 代码内容: View Code <html><HEAD&g ...

  10. HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)

    摘要:本节主要来讲解Android10.0 JAVA层的HIDL服务创建和JAVA层的Client验证 阅读本文大约需要花费15分钟. 文章首发微信公众号:IngresGe 专注于Android系统级 ...

最新文章

  1. socket recv 服务端阻塞 python_网络编程(基于socket编程)
  2. 怎么看电脑的hdmi是输出还是输入_HDMI线连接电视电脑常见问题及解决办法
  3. Linux Shell脚本攻略学习总结:一
  4. Python数据类型知识点
  5. Rete之外的生活– RIP Rete 2013 :)
  6. kotlin 计算平方_Kotlin程序计算自然数之和
  7. ios 时间戳 当前时间 相互转化
  8. 讓combobox也綁定數據表
  9. import org.eclipse.californium.scandium.DTLSConnector;
  10. 姓名的首字母组成的图案C语言怎么编,c语言编写一个程序,根据用户输入英文名和姓先显示姓氏,其后跟一个逗号,然后显示名的首字母:...
  11. 绿盟科技网络安全威胁周报2017.02 请关注Microsoft Edge远程权限提升漏洞 CVE-2017-0002...
  12. ext2文件系统源代码之balloc.c文件解析
  13. 睿智的目标检测51——Tensorflow2搭建yolo3目标检测平台
  14. 互联网公司中秋节礼盒大比拼(2019版)
  15. 软件开发之大忌:想当然
  16. 判断用户是否已关注公众号
  17. 关于web项目log日志指定输出文件位置配置
  18. 如何查看Linux系统的状态信息?
  19. 中国机器人产业图谱(2022)
  20. 【硬刚大数据】企业级大数据平台建设参考 | 淘宝滴滴美团360快手京东

热门文章

  1. IDEA常用快捷键总结
  2. 一个函数中写多少行代码比较合适呢?
  3. Java的日期类说明Calendar、Data、日期转化格式化以及注意事项
  4. 一步一步学Repast 第四章——分析SimpleModel
  5. moodle安装图解
  6. Chinapub 100万会员评选出来的2007年IT图书排行榜
  7. 简易旋转倒立摆设计报告
  8. C语言之父Dennis Ritchie告诉你:如何成为世界上最好的程序员?
  9. matlab 暂态稳定性,基于MATLAB的电力系统暂态稳定性仿真
  10. Exescope等打开DLL,导出函数名称混乱的问题