一、页面准备
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>管理员登录</title>
<link rel="stylesheet" href="http://culturestore.oss-cn-shanghai.aliyuncs.com/normalize/normalize.css">
<link href="${basePath }/static/admin/css/dockingLogin.css" rel="stylesheet">
<script type="text/javascript" src="${basePath }/static/easyui/jquery.min.js" ></script>
<script type="text/javascript" src="${basePath }/static/common/js/jQuery.md5.js"></script>
<script type="text/javascript" src="${basePath }/static/common/js/base64code.js"></script>
<script type="text/javascript">
function befSubmit(){
var pwd = $("#pwd").val();
pwd = $.md(pwd);
var pwdmd5 = $.md5(pwd);
$("#pwd").val(pwdmd5);
}
$(function(){
var topURI = window.parent.location;
var nowURI = window.location;
if (topURI != nowURI){
window.parent.location.reload();
}
});
function myReload() {
document.getElementById("CreateCheckCode").src =
document.getElementById("CreateCheckCode").src+ "?nocache=" + new Date().getTime();
}
</script>
</head>
<body class="loginBg">
<form action="${basePath}/admin/doLogin" method="post" onsubmit="return befSubmit()">
<div class="sjdj-login-bg">
<div class="sjdj-login-main">
<div class="sjdj-login-tit">
<div class="wen-1">欢迎登录</div>
<div class="wen-2">数据对接管理</div>
</div>
<div class="sjdj-login-wrap">
<img class="tit-img" src="http://culturecloud.img-cn-hangzhou.aliyuncs.com/wangxiaosong/image/2020923142928JWMjOgv1v10uxFefUs43KfvA1WXDp1.png">
<input class="txtInp" type="hidden" name="channel" value="1"/>
<div class="qItem clearfix">
<input class="txtInp" type="text" placeholder="User ID" name="username">
</div>
<div class="qItem clearfix">
<input class="txtInp" type="password" placeholder="Password" name="password" id="pwd">
</div>
<div class="qItem clearfix">
<input class="txtInp yzmInp" type="text" placeholder="验证码" name="checkCode">
<div class="yzmBox"><img src="${basePath }/pictureCheckCode" id="CreateCheckCode" onclick="myReload()"></div>
</div>
<button class="q-btn" type="submit">登 录</button>
</div>
</div>
</div>
</form>
</body>
</html>
二、后台画好图片以流的形式响应到页面
package com.creatoo.hn.web.servlet;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
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;
import javax.servlet.http.HttpSession;
@WebServlet("/pictureCheckCode")
public class PictureCheckCode extends HttpServlet {
private static final long serialVersionUID = 1L;
public Color getRandColor(int s, int e) {
Random random = new Random();
if (s > 255)
s = 255;
if (e > 255)
e = 255;
int r, g, b;
r = s + random.nextInt(e - s);
g = s + random.nextInt(e - s);
b = s + random.nextInt(e - s);
return new Color(r, g, b);
}
private Random r = new Random();
private String codes = "23456789abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYXZ";
private char randomChar() {
int index = r.nextInt(codes.length());
return codes.charAt(index);
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "No-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");
int width = 80, height = 35;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
Graphics2D g2d = (Graphics2D) g;
Random random = new Random();
Font mfont = new Font("楷体", Font.BOLD, 25);
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height);
g.setFont(mfont);
g.setColor(getRandColor(180, 200));
for (int i = 0; i < 100; i++) {
int x = random.nextInt(width - 1);
int y = random.nextInt(height - 1);
int x1 = random.nextInt(6) + 1;
int y1 = random.nextInt(12) + 1;
BasicStroke bs = new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL);
Line2D line = new Line2D.Double(x, y, x + x1, y + y1);
g2d.setStroke(bs);
g2d.draw(line);
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 4; ++i) {
String sTemp = String.valueOf(randomChar());
sb.append(sTemp);
Color color = new Color(20 + random.nextInt(110), 20 + random.nextInt(110), random.nextInt(110));
g.setColor(color);
Graphics2D g2d_word = (Graphics2D) g;
AffineTransform trans = new AffineTransform();
trans.rotate((45) * 3.14 / 180, 15 * i + 8, 7);
float scaleSize = random.nextFloat() + 0.8f;
if (scaleSize > 1f)
scaleSize = 1f;
trans.scale(scaleSize, scaleSize);
g2d_word.setTransform(trans);
g.drawString(sTemp, 15 * i + 18, 14);
}
HttpSession session = request.getSession(true);
session.setAttribute("randCheckCode", sb.toString());
System.out.println("sRand="+sb.toString());
g.dispose();
ImageIO.write(image, "JPEG", response.getOutputStream());
}
}
三、后台校验
if("".equals(checkCode) || !checkCode.equalsIgnoreCase((String) session.getAttribute("randCheckCode"))){
opsForValue.increment("SHIRO_LOGIN_COUNT"+username, 1);
int count=Integer.parseInt(opsForValue.get("SHIRO_LOGIN_COUNT"+username));
if(count==1) {
stringRedisTemplate.expire("SHIRO_LOGIN_COUNT" + username, 10, TimeUnit.MINUTES);
}
if(Integer.parseInt(opsForValue.get("SHIRO_LOGIN_COUNT"+username))>=5){
opsForValue.set("SHIRO_IS_LOCK"+username, "LOCK");
stringRedisTemplate.expire("SHIRO_IS_LOCK"+username, 1, TimeUnit.HOURS);
}
view.addObject("msg", "验证码错误!");
if(count>=3 && count<5){
view.addObject("msg", "您已经登录失败"+count+"次,失败5次账号将被锁定1小时!");
}else if(count==5){
view.addObject("msg", "您的账号已经被锁定,请1小时后再操作!");
}
view.setViewName("admin/login");
return view;
}
四、效果图
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201013164600204.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMjU5MjYx,size_16,color_FFFFFF,t_70#pic_center)