因为没怎么做网页端的功能, 一直不知道登陆验证码是怎么实现的, 这次学习梳理一下:
1. web 端展示的是图片, 有后台服务 (如 sevlet 返回一个图片)
2. 每次展示 / 刷新图片, 请求一次服务端, Web 端生成一个唯一 ID 传到服务端, 服务端保存该唯一 ID 与生成的验证码的对应关系, 并返回图片
3. 登陆请求参数包含用户名和密码, 唯一 ID 和用户录入的验证码
4. 登陆后台服务要验证用户录入的验证码与根据唯一 ID 找到的服务端缓存的验证码是否一致, 如果不一致则报错. 如果一致, 在继续校验用户名和密码是否正确
vue Web 端代码
通过改变图片的 src 达到重新请求, 刷新图片的目的. 刚好我们要传输 uuid 到服务端
- <template>
- <div>
- <h4>{{newsTitle}}</h4>
- <hr>
- <!-- 每次 uuid 的值发送变化则刷新图片 -->
- <img :src="this.codeurl+this.uuid" @click="getCaptcha()">
- <button @click="getCaptcha()"> 刷新 </button>
- </div>
- </template>
- <script>
- import store from '../vuex/store.JS';
- export default {
- data(){
- return {
- newsTitle :'验证码',
- uuid :'',
- codeurl : "http://127.0.0.1:8088/EasyUI/VerifyCode.do?uuid=",
- currentcode:'0000',
- captchaPath:''
- }
- },
- store,
- methods:{
- getUUID(){
- /* 获取一个唯一 ID */
- var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
- return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
- });
- return uuid;
- },
- getCaptcha(){
- /* 刷新验证码图片 */
- this.uuid = this.getUUID();
- console.log(uuidtmp);
- },
- },
- mounted(){
- /* 初始化验证码图片 */
- this.uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
- return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
- });
- }
- }
- </script>
- <style>
- </style>
服务端代码: servlet 主要是生成随机验证码及其图片
-- 生成图片的代码来源于网络
- package Serverlet;
- import java.awt.Color;
- import java.awt.Font;
- import java.awt.Graphics;
- import java.awt.image.BufferedImage;
- import java.io.IOException;
- import java.util.Random;
- 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;
- /**
- * Servlet implementation class LoginServlet
- */
- @WebServlet(name="VerifyCode.do", urlPatterns="/VerifyCode.do")
- public class VerifyCodeServlet extends HttpServlet {
- private static final long serialVersionUID = 1L;
- /**
- * @see HttpServlet#HttpServlet()
- */
- public VerifyCodeServlet() {
- super();
- // TODO Auto-generated constructor stub
- }
- /**
- * Initialization of the servlet. <br>
- * @throws ServletException if an error occurs
- */
- public void init() throws ServletException {
- // Put your code here
- }
- /**
- * Destruction of the servlet. <br>
- */
- public void destroy() {
- super.destroy(); // Just puts "destroy" string in log
- // Put your code here
- }
- /**
- * The doGet method of the servlet. <br>
- *
- * This method is called when a form has its tag value method equals to get.
- *
- * @param request the request send by the client to the server
- * @param response the response send by the server to the client
- * @throws ServletException if an error occurred
- * @throws IOException if an error occurred
- */
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- this.doPost(request, response);
- }
- /**
- * The doPost method of the servlet. <br>
- *
- * This method is called when a form has its tag value method equals to post.
- *
- * @param request the request send by the client to the server
- * @param response the response send by the server to the client
- * @throws ServletException if an error occurred
- * @throws IOException if an error occurred
- */
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- response.setContentType("image/jpeg");
- request.setCharacterEncoding("utf-8");
- response.setCharacterEncoding("utf-8");
- String uuid = request.getParameter("uuid");
- System.out.println(uuid);
- // 声明验证码
- int width = 80;
- int height = 30;
- String data = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789abcdefghijklmnpqrstuvwxyz"; // 随机字符字典, 其中 0,o,1,I 等难辨别的字符最好不要
- Random random = new Random();// 随机类
- //1 创建图片数据缓存区域 (核心类)
- BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 创建一个彩色的图片
- //2 获得画板 (图片, ps 图层), 绘画对象.
- Graphics g = image.getGraphics();
- //3 选择颜色, 画矩形 3,4 步是画一个有内外边框的效果
- g.setColor(Color.BLACK);
- g.fillRect(0, 0, width, height);
- //4 白色矩形
- g.setColor(Color.WHITE);
- g.fillRect(1, 1, width-2, height-2);
- /**1 提供缓存区域, 为了存放 4 个随机字符, 以便存入 session */
- StringBuilder builder = new StringBuilder();
- //5 随机生成 4 个字符
- // 设置字体颜色
- g.setFont(new Font("宋体", Font.BOLD&Font.ITALIC, 25));
- for(int i = 0 ; i < 4 ;i ++){
- // 随机颜色
- g.setColor(new Color(random.nextInt(255),random.nextInt(255), random.nextInt(255)));
- // 随机字符
- int index = random.nextInt(data.length());
- String str = data.substring(index, index + 1);
- //String str = code.substring(i,i+1);
- /**2 缓存 */
- builder.append(str);
- // 写入
- g.drawString(str, (width / 6) * (i + 1) , 20);
- }
- // 给图中绘制噪音点, 让图片不那么好辨别
- for(int j=0,n=random.nextInt(100);j<n;j++){
- g.setColor(Color.RED);
- g.fillRect(random.nextInt(width),random.nextInt(height),1,1);// 随机噪音点
- }
- /**3 获得随机数据, 并保存 session*/
- String tempStr = builder.toString();
- request.getSession().setAttribute("sessionCacheData",tempStr);
- //.. 生成图片发送到浏览器 -- 相当于下载
- ImageIO.write(image, "jpg", response.getOutputStream());
- }
- }
- View Code
以上未含包含 uuid 与验证码的对应关系以及登陆验证的代码
来源: http://www.bubuko.com/infodetail-2775243.html