登录验证码demo-java
时间:2022-04-22
本文章向大家介绍登录验证码demo-java,主要内容包括1、java部分-CaptchaController.java、2、html部分-login.html、3、效果、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
在一些类似于管理系统的项目中,我们在登录时经常会用到图片验证码。这里把我自己写的一个小系统(后台是java语言)的验证码部分摘出来。
总体思路是后端有一个生成验证码图片的接口,把验证码图片写入浏览器,前端页面在img标签里的src属性里填写后端生成验证码图片的接口地址即可。
1、java部分-CaptchaController.java
我这里是把后端生成的验证码生成图片返回给浏览器时,同时存入到了数据库中,前端登录时,后端根据前端输入的验证码和数据库中的验证码作对比,来判断是否可以登录。
package com.lin.controller;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.lin.domain.Captcha;
import com.lin.service.SysUserService;
/**
* 验证码-controller
* @author libo
*/
@Controller
@RequestMapping("/captcha")
public class CaptchaController {
@Autowired
private SysUserService uService;
/**
* 随机字符字典
*/
private static final char[] CHARS = { '2', '3', '4', '5', '6', '7', '8',
'9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M',
'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm',
'n', 'p', 'q', 'r', 's', 't', 'u' ,'v', 'w', 'x', 'y', 'z'};
/**
* 随机数
*/
private static Random random = new Random();
/**
* 获取4位随机数
* @return
*/
private static String getRandomString() {
StringBuffer buffer = new StringBuffer();
for(int i = 0; i < 4; i++) {
buffer.append(CHARS[random.nextInt(CHARS.length)]);
}
return buffer.toString();
}
/**
* 获取随机数颜色
* @return
*/
private static Color getRandomColor() {
return new Color(random.nextInt(255),random.nextInt(255), random.nextInt(255));
}
/**
* 返回某颜色的反色
* @param c
* @return
*/
private static Color getReverseColor(Color c) {
return new Color(255 - c.getRed(), 255 - c.getGreen(), 255 - c.getBlue());
}
/**
* 生成验证码
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
@ResponseBody
@RequestMapping(value="/getCaptcha.do", method=RequestMethod.GET)
public void outputCaptcha(HttpServletRequest request, HttpServletResponse response, String rad)
throws ServletException, IOException {
// 设置页面不缓存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");
String randomString = getRandomString(); //生成的验证码
Captcha c = new Captcha();
c.setCaptchaId(rad);
c.setCaptcha(randomString.toUpperCase());
Integer id = uService.saveCaptcha(c);//保存验证码到数据库中
if(id > 0){ //验证码保存成功
}else{ //验证码保存失败
return;
}
int width = 100; //验证码图像的宽度
int height = 34; //验证码图像的高度
// 在内存中创建图象
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
for(int i=0; i<randomString.length(); i++){
Color color = getRandomColor();
Color reverse = getReverseColor(color);
g.setColor(color); //设置字体颜色
g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 25)); //设置字体样式
g.fillRect(0, 0, width, height);
g.setColor(reverse);
g.drawString(randomString, 18, 25);
}
//随机生成一些点
for (int i = 0, n = random.nextInt(100); i < n; i++) {
g.drawRect(random.nextInt(width), random.nextInt(height), 1, 1);
}
// 随机产生干扰线,使图象中的认证码不易被其它程序探测到
for (int i = 0; i < 10; i++) {
g.setColor(getRandomColor());
final int x = random.nextInt(width-1); // 保证画在边框之内
final int y = random.nextInt(height-1);
final int xl = random.nextInt(width);
final int yl = random.nextInt(height);
g.drawLine(x, y, x + xl, y + yl);
}
g.dispose(); //图像生效
ImageIO.write(bi, "JPEG", response.getOutputStream()); //输出图片到页面
}
}
2、html部分-login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>后台管理系统登录</title>
<link rel="stylesheet" href="/common/css/index.css">
<script src="/scripts/apiConfig.js"></script>
<script src="/lib/jquery/jquery.min.js"></script>
<script src="/lib/aes/aes.min.js"></script>
<script src="/common/js/utils.js"></script>
</head>
<body>
<div class="layout">
<div class="top-name">后台管理系统
<span>Background Management System</span>
</div>
<div class="main">
<div class="item">
<label style="word-spacing: 10px;">邮 箱:</label>
<input type="text" id="loginEmail" class="f-s-14" autocomplete="off" placeholder="请输入邮箱">
<span class="err-tip" id="tipLEmail" ng-class="m-l-15"></span>
</div>
<div class="item">
<label style="word-spacing: 10px;">密 码:</label>
<input type="password" id="loginPwd" class="f-s-14" autocomplete="off" placeholder="请输入密码">
<span class="err-tip " id="tipLPwd" ng-class="m-l-15"></span>
</div>
<div class="item clearfix">
<label>验证码:</label>
<input type="text" id="captcha" class="f-s-14" placeholder="请输入验证码" style="width: 200px;">
<a href="javascript:void(0);" onclick="updateCaptcha()" style="height: 36px;width: 100px;float: right;">
<img src="" alt="" id="captcha_img">
</a>
<span class="err-tip" id="tipCaptcha" ng-class="m-l-15"></span>
</div>
<div style="text-align: center;margin-top: -10px;height: 20px;margin-bottom: 5px;">
<span class="err-tip" id="error" ng-class="m-l-15" style="font-size: 14px;"></span>
</div>
<div class="item">
<button type="button" class="submit" id="submit" style="outline: none;">登 录</button>
</div>
</div>
</div>
</body>
<script>
//更新验证码
var random = '';
function updateCaptcha() {
random = new Date().getTime()+''+Math.floor(Math.random() * Math.pow(10, 8));
$('#captcha_img').attr('src', hostObj.host+'/captcha/getCaptcha.do?rad='+random);
}
$(function () {
//页面加载的时候就获取验证码
updateCaptcha();
$('#loginEmail').blur(function () {
checkLoginEmail();
});
$('#loginPwd').blur(function () {
checkLoginPwd();
});
$('#captcha').blur(function () {
checkCaptcha();
});
$("#submit").click(function() {
var flag1 = checkLoginEmail();
var flag2 = checkLoginPwd();
var flag3 = checkCaptcha();
if(!flag1 || !flag2 || !flag3){
return;
}
$.ajax({
type:'post',
url: hostObj.host+'/sysUser/login.do',
dataType:"json",
data:{
loginEmail:$("#loginEmail").val(),
loginPwd:encrypt($("#loginPwd").val()),
captcha: $('#captcha').val(),
captchaId: random
},
success:function(res) {
if(res.success == 1){
var user = {
id: res.data.id,
email: res.data.email,
createTime: res.data.createTime.substring(0,19),
lastLoginTime: res.data.lastLoginTime.substring(0,19),
status: res.data.status
}
window.location.href = "main.html";
}else{
$('#error').html(res.error.msg);
if(res.error.code == 4000){
$('#captcha').focus();
}
}
},
error:function(res){
$('#error').html('系统错误!');
}
});
});
function checkLoginEmail() {
if($.trim($('#loginEmail').val()) == ''){
$('#tipLEmail').html('请输入邮箱');
return false;
}else{
$('#tipLEmail').html('');
return true;
}
}
function checkLoginPwd() {
if($.trim($('#loginPwd').val()) == ''){
$('#tipLPwd').html('请输入登录密码');
return false;
}else{
$('#tipLPwd').html('');
return true;
}
}
function checkCaptcha() {
if($.trim($('#captcha').val()) == ''){
$('#tipCaptcha').html('请输入验证码');
return false;
}else{
$('#tipCaptcha').html('');
return true;
}
}</script>
</html>
3、效果
- web中的水晶报表 "出现通信错误。将停止打印"
- nginx反向代理中proxy_set_header 运维笔记
- 期待已久的直播能力开放了!年底之前来波大的
- 两个目录中,删除其中一个目录中同名文件的做法
- linux下监控某个目录是否被更改
- centos下升级git版本的操作记录
- linux下core file size设置笔记
- linux下文件加密操作记录
- python的with语句,超级强大
- “AS3.0高级动画编程”学习:第二章转向行为(上)
- Linux下性能调试工具-top和sar运维笔记
- Apache+wsgi+flask部署
- “勒索病毒”到底会勒索啥,尽可以做到让全球对之恐惧无奈!
- 解决win10 关键错误开始菜单和cortana无法工作 的问题(转-真的成功了)
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释