因为没怎么做网页端的功能,一直不知道登陆验证码是怎么实现的,这次学习梳理一下:
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()" alt="">
<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与验证码的对应关系以及登陆验证的代码