昆明网站设计制作公司,淮南教育网官网,wordpress完全版教材,好听有创意的广告公司名字登录添加图形验证码#xff1a;
在 Java 中#xff0c;我们可以使用一些图形处理库#xff08;如 java.awt 和 javax.imageio#xff09;生成图形验证码#xff0c;并将验证码文本存储在会话#xff08;session#xff09;中以供验证。下面是一个完整的实现步骤#x…登录添加图形验证码
在 Java 中我们可以使用一些图形处理库如 java.awt 和 javax.imageio生成图形验证码并将验证码文本存储在会话session中以供验证。下面是一个完整的实现步骤包括 验证码图片生成、验证码接口、以及 验证逻辑。 1. Maven 依赖可选
如需引入依赖管理可以使用 Maven 项目结构。示例中我们主要依赖 Java 自带的 javax 库所以无需添加额外依赖。
如果你需要更多验证码功能kaptcha 是一个常用的 Java 验证码生成库可以通过 Maven 添加
xml
dependencygroupIdcom.github.penggle/groupIdartifactIdkaptcha/artifactIdversion2.3.2/version
/dependency 2. 验证码生成与接口实现
下面是一个使用 javax.imageio 和 java.awt 库生成验证码图片的例子并通过 Servlet 提供 HTTP 接口。
生成验证码的 Java Servlet
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;WebServlet(/captcha)
public class CaptchaServlet extends HttpServlet {private static final int WIDTH 160;private static final int HEIGHT 40;Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 创建验证码图片BufferedImage captchaImage new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);Graphics2D g (Graphics2D) captchaImage.getGraphics();Random random new Random();// 生成随机验证码文本String captchaText generateCaptchaText(6);HttpSession session request.getSession();session.setAttribute(captcha, captchaText); // 将验证码存储在 session 中// 设置图片背景颜色g.setColor(Color.LIGHT_GRAY);g.fillRect(0, 0, WIDTH, HEIGHT);// 设置字体与颜色g.setFont(new Font(Arial, Font.BOLD, 30));g.setColor(Color.BLACK);g.drawString(captchaText, 20, 30);// 画干扰线for (int i 0; i 5; i) {g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));int x1 random.nextInt(WIDTH);int y1 random.nextInt(HEIGHT);int x2 random.nextInt(WIDTH);int y2 random.nextInt(HEIGHT);g.drawLine(x1, y1, x2, y2);}g.dispose(); // 释放资源// 设置响应类型为图片格式response.setContentType(image/png);ImageIO.write(captchaImage, png, response.getOutputStream()); // 输出图片}// 生成随机验证码文本private String generateCaptchaText(int length) {String chars ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789;StringBuilder sb new StringBuilder();Random random new Random();for (int i 0; i length; i) {sb.append(chars.charAt(random.nextInt(chars.length())));}return sb.toString();}
}
解释
CaptchaServlet 使用 BufferedImage 创建验证码图片。使用 Graphics2D 在图片上绘制文字和干扰线。验证码文本存储在 session 中以便后续验证。
会话存储session.setAttribute(captcha, captchaText); 将验证码保存到用户会话中。图片响应ImageIO.write(captchaImage, png, response.getOutputStream()); 将图片直接写入 HTTP 响应流中。 3. 验证码验证逻辑
在用户提交表单时后端需要验证用户输入的验证码与 session 中存储的验证码是否一致。
登录接口示例
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;WebServlet(/login)
public class LoginServlet extends HttpServlet {Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String userAccount request.getParameter(userAccount);String userPassword request.getParameter(userPassword);String captchaInput request.getParameter(captcha);HttpSession session request.getSession();String captcha (String) session.getAttribute(captcha);// 验证验证码是否正确if (captcha null || !captcha.equalsIgnoreCase(captchaInput)) {response.getWriter().write(验证码错误);return;}// TODO: 验证账号和密码的逻辑if (admin.equals(userAccount) password.equals(userPassword)) {response.getWriter().write(登录成功);} else {response.getWriter().write(账号或密码错误);}}
}
解释
验证码验证获取用户输入的验证码并与会话中的验证码进行比对。忽略大小写使用 equalsIgnoreCase 忽略大小写进行比较。验证逻辑如果验证码正确且账号密码验证成功则返回“登录成功”。 4. 前端代码提交表单与验证码显示
前端代码需要请求验证码图片并将验证码输入框的内容一并提交给后端。
HTML 示例
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title登录页面/title
/head
bodyform action/login methodPOSTinput typetext nameuserAccount placeholder请输入账号 required /input typepassword nameuserPassword placeholder请输入密码 required /img src/captcha alt验证码 onclickthis.src/captcha?Math.random() /input typetext namecaptcha placeholder请输入验证码 required /button typesubmit登录/button/form
/body
/html
解释
验证码刷新点击验证码图片时通过 this.src/captcha? Math.random() 强制刷新验证码。表单提交在用户填写验证码后将表单提交到 /login 接口。 使用行为验证码
在开发中添加行为验证码是一种有效的防止自动化攻击和机器人行为的方式。以下是一些免费且公开可用的行为验证码解决方案
1. hCaptcha
概述hCaptcha 是一个免费的验证码服务提供用户交互验证防止恶意自动化。特点 简单易用与 Google reCAPTCHA 类似。提供奖励系统网站可以通过用户完成验证获取收益。
使用 访问 hCaptcha官网 注册并获取 API 密钥。根据文档进行集成。
2. Google reCAPTCHA
概述虽然 reCAPTCHA 主要是为识别机器人设计的但其 Checkbox 和 Invisible 选项可以用作行为验证码。特点 广泛使用用户熟悉。提供多种验证方式包括隐形验证。
使用 注册 Google reCAPTCHA 获取密钥。按照文档进行集成。
3. Friendly Captcha
概述Friendly Captcha 提供了一种不依赖于用户交互的验证码系统适合于保护用户隐私。特点 不需要用户填写验证码用户体验更佳。通过计算资源验证用户行为。
使用 访问 FriendlyCaptcha官网 注册并获取 API 密钥。根据文档进行集成。 实战hCaptcha
在vue项目中创建组件
templatediv!-- hCaptcha 容器 --divrefhcaptchaContainerclassh-captcha:data-sitekeysiteKey/div/div
/templatescript setup langts
import { onMounted, ref, defineEmits } from vue;
const token refstring | null(null); // 存储验证 token// 定义事件向父组件发送 token
const emit defineEmits([verify]);
interface Props {siteKey: string;
}// const props definePropsProps(); // 接收 siteKey 作为参数
const hcaptchaContainer refHTMLDivElement | null(null); // hCaptcha 容器的引用// 生命周期钩子确保 hCaptcha 在组件挂载后初始化
onMounted(() {if (window.hcaptcha) {console.log(hCaptcha 已加载);window.hcaptcha.render(hcaptchaContainer.value!, {sitekey: 10000000-ffff-ffff-ffff-000000000001,callback: onVerify,// sitekey: fbc8723c-c356-49d6-a524-bf327f9ac81a,});} else {console.error(hCaptcha 脚本未加载);}
});const onVerify (response: string) {console.log(hCaptcha 验证成功token:, response);emit(verify, response); // 通过事件发送 token 给父组件
};
/scriptstyle
.h-captcha {margin: 10px 0;
}
/style 然后在登录页面中使用并且进行拦截
templatediv iduserLoginViewh1 stylemargin-bottom: 56px; color: #fff用户登录/h1a-formstyledisplay: flex;flex-direction: column;justify-content: space-between;max-width: 520px;min-height: 350px;margin: 0 auto;background: rgba(255, 255, 255, 0.9);padding: 20px;border-radius: 10px;box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);label-alignleftauto-label-width:modelformsubmithandleSubmita-form-item fielduserAccount label账号 stylemargin-top: 40pxa-input v-modelform.userAccount placeholder请输入账号 //a-form-itema-form-item fielduserPassword tooltip密码不少于 8 位 label密码a-input-passwordv-modelform.userPasswordplaceholder请输入密码//a-form-itemHCaptcha verifyonCaptchaVerify /a-form-item stylemargin-bottom: 40pxa-buttontypeprimaryhtml-typesubmitstylewidth: 120px; height: 40px; margin-right: 20%登录/a-buttona-buttontypeprimaryclickturnToRegister()stylewidth: 120px; height: 40px; margin-left: 20%新用户注册/a-button/a-form-item/a-form/div
/templatescript setup langts
import HCaptcha from ../../components/HCaptcha.vue;
import { reactive, ref } from vue;
import { UserControllerService, UserLoginRequest } from ../../../generated;
import message from arco-design/web-vue/es/message;
import { useRouter } from vue-router;
import { useStore } from vuex;/*** 表单信息*/
const form reactive({userAccount: ,userPassword: ,
} as UserLoginRequest);const router useRouter();
const store useStore();const captchaToken refstring | null(null); // 存储 hCaptcha 的 token
const onCaptchaVerify (token: string) {captchaToken.value token; // 接收 hCaptcha 的 token
};/*** 提交表单* param data*/
const handleSubmit async () {if (!captchaToken.value) {message.error(请先通过验证码验证);return; // 阻止提交}const res await UserControllerService.userLoginUsingPost(form);// 登录成功跳转到主页if (res.code 0) {await store.dispatch(user/getLoginUser);router.push({path: /,replace: true,});} else {message.error(登陆失败 res.message);}
};/*** 跳转到注册页面*/
const turnToRegister () {router.push({path: /user/register,replace: true,});
};
/script
style
#userLoginView {margin-top: 20vh;/*margin-left: 40vh;*/
}
/style