前言:认证在互联网中会经常见到,其主要作用是安全问题中防止恶意破解、刷票等。在系统开发中认证的实现也有很多种,什么手机短信认证,邮箱认证等。在这里我使用最基本的验证码的形式进行认证,下面例出过程。

验证码工具类(用来生成验证码)

创建一个简单的验证码生成器,通过流的方式将随机字体、随机背景色、干扰线、随机字符串,夹杂在一起形成验证码图片

  1. import javax.imageio.ImageIO;
  2. import java.awt.*;
  3. import java.awt.image.BufferedImage;
  4. import java.io.IOException;
  5. import java.io.OutputStream;
  6. import java.util.Random;
  7. /**
  8. * 自定义验证码类
  9. */
  10. public class VerifyCode {
  11. private int width = 100; //生成验证码图片的宽度
  12. private int height = 40; //生成验证码图片的高度
  13. private String[] fontNames = {"宋体","楷体","隶书","微软雅黑"};
  14. private Color bgColor = new Color(255,255,255); //定义验证码图片的背景色
  15. private Random random = new Random();
  16. private String codes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  17. private String text; //记录随机字符串
  18. /**
  19. * 获取随机一个颜色
  20. * @return
  21. */
  22. private Color randomColor(){
  23. int red = random.nextInt(150);
  24. int green = random.nextInt(150);
  25. int blue = random.nextInt(150);
  26. return new Color(red,green,blue);
  27. }
  28. /**
  29. * 获取随机一个字体
  30. * @return
  31. */
  32. private Font randomFont(){
  33. String name = fontNames[random.nextInt(fontNames.length)];
  34. int style = random.nextInt(4);
  35. int size =random.nextInt(5)+24;
  36. return new Font(name,style,size);
  37. }
  38. /**
  39. * 获取随机一个字符
  40. * @return
  41. */
  42. private char randomChar(){
  43. return codes.charAt(random.nextInt(codes.length()));
  44. }
  45. /**
  46. * 创建一个空白的BufferedImage对象
  47. * @return
  48. */
  49. private BufferedImage createImage(){
  50. BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  51. Graphics2D g2 = (Graphics2D)image.getGraphics();
  52. g2.setColor(bgColor);
  53. g2.fillRect(0,0,width,height);
  54. return image;
  55. }
  56. /**
  57. * 绘制干扰线
  58. */
  59. private void drawLine(BufferedImage image){
  60. Graphics2D g2 = (Graphics2D) image.getGraphics();
  61. int num = 5;
  62. for (int i = 0 ;i < num ; i++){
  63. int x1 = random.nextInt(width);
  64. int y1 = random.nextInt(height);
  65. int x2 = random.nextInt(width);
  66. int y2 = random.nextInt(height);
  67. g2.setColor(randomColor());
  68. g2.setStroke(new BasicStroke(1.5f));
  69. g2.drawLine(x1, y1, x2, y2);
  70. }
  71. }
  72. /**
  73. * 绘制验证码
  74. * @return
  75. */
  76. public BufferedImage getImage(){
  77. BufferedImage image = createImage();
  78. Graphics2D g2 = (Graphics2D) image.getGraphics();
  79. StringBuffer sb = new StringBuffer();
  80. for (int i = 0 ; i < 4 ; i++){
  81. String s = randomChar() + "";
  82. sb.append(s);
  83. g2.setColor(randomColor());
  84. g2.setFont(randomFont());
  85. float x = i * width * 1.0f / 4;
  86. g2.drawString(s,x,height - 15);
  87. }
  88. this.text = sb.toString();
  89. drawLine(image);
  90. return image;
  91. }
  92. public String getText(){
  93. return text;
  94. }
  95. /**
  96. * 用流传输方法
  97. * @return
  98. */
  99. public static void output(BufferedImage image, OutputStream out) throws IOException {
  100. ImageIO.write(image,"JPEG",out);
  101. }
  102. }

controller层调用

创建VerifyCode验证码生成器实例,将text(随机字符串)存入session中,将图片用流的方式传入前段

  1. import javax.servlet.http.HttpServletRequest;
  2. import javax.servlet.http.HttpServletResponse;
  3. import javax.servlet.http.HttpSession;
  4. import java.awt.image.BufferedImage;
  5. import java.io.IOException;
  6. @RestController
  7. public class VerifyCodeController {
  8. @GetMapping("/vercode")
  9. public void code(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  10. //创建验证码生成器实例取得生成图片和随机字符串
  11. VerifyCode vc = new VerifyCode();
  12. BufferedImage image = vc.getImage();
  13. String text = vc.getText();
  14. //随机字符串存入session中
  15. HttpSession session = req.getSession();
  16. session.setAttribute("index_code",text);
  17. //用流传输
  18. VerifyCode.output(image,resp.getOutputStream());
  19. }
  20. }

前段

前段我这里使用的是vue框架(使用什么框架不是问题,姑且提一下),img图片中src路劲调用

  1. <img src="/vercode" alt="">

启动服务器,测试,获取成功

前段-输入

我这里做登录认证,表单加入验证码输入

  1. <tr>
  2. <td>
  3. <el-tag>验证码</el-tag>
  4. </td>
  5. <td>
  6. <el-input size="mini" v-model="user.code" pleceholder="请输入验证码"></el-input>
  7. </td>
  8. <td>
  9. <img src="/vercode" alt="">
  10. </td>
  11. </tr>

使用spring security做后台的验证

这里只提取验证码相关的:

过滤器

自定义过滤器,继承GenericFilterBean,重写doFilter方法

  1. @Component
  2. public class VerifyCodeFilter extends GenericFilterBean {
  3. //绑定登录路径
  4. private String defaultFilterProcessUrl = "/doLogin";
  5. @Override
  6. public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
  7. HttpServletRequest request = (HttpServletRequest) req;
  8. HttpServletResponse response = (HttpServletResponse) resp;
  9. if ("POST".equalsIgnoreCase(request. getMethod()) && defaultFilterProcessUrl.equals(request.getServletPath())){
  10. String requestCaptcha = request.getParameter("code");
  11. String genCaptcha = (String) request.getSession().getAttribute("index_code");
  12. if(StringUtils.isEmpty(requestCaptcha)){
  13. throw new AuthenticationServiceException("验证码不能为空!");
  14. }
  15. if (!genCaptcha.toLowerCase().equals(requestCaptcha.toLowerCase())){
  16. throw new AuthenticationServiceException("验证码错误!");
  17. }
  18. }
  19. chain.doFilter(request,response);
  20. }
  21. }

安全配置器

继承WebSecurityConfigurerAdapter类,重写认证方法

  1. @Configuration
  2. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  3. @Autowired
  4. VerifyCodeFilter verifyCodeFilter;
  5. @Override
  6. public void configure(WebSecurity web) throws Exception {
  7. //防止验证图片被拦截
  8. web.ignoring().antMatchers("/vercode");
  9. }
  10. @Override
  11. protected void configure(HttpSecurity http) throws Exception {
  12. //对前段获取到的验证数据进行验证
  13. http.addFilterBefore(verifyCodeFilter,UsernamePasswordAuthenticationFilter.class);
  14. http.authorizeRequests()
  15. //省略账号密码认证
  16. ...
  17. ...
  18. ...
  19. .permitAll()
  20. .and()
  21. .csrf().disable()
  22. }
  23. }

登录测试

这次就到这里,有什么问题或建议可以在下面评论。

积累点点滴滴,一步一脚印,加油

java代码实现简单的认证——图片验证码形式的更多相关文章

  1. Java之英格玛简单实现以及加密验证码的应用

    最近看了一部电影<模仿游戏>,<模仿游戏>中艾伦·图灵破译英格玛让我对英格玛产生了好奇,于是就开始翻阅资料对其进行研究,但是毕竟智慧有限,所以我这里用Java实现一个简单的英格 ...

  2. Jmeter4.0---- jmeter中写入java代码_简单了解(15)

    1.说明 BeanShell:是一个小型嵌入式Java源代码解释器,具有对象脚本语言特性,能够动态地执行标准JAVA语法,并利用在JavaScript和Perl中常见的的松散类型.命令.闭包等通用脚本 ...

  3. Python简单的制作图片验证码

    -人人可以学Python--这里示范的验证码都是简单的,你也可以把字符扭曲 人人可以学Python.png Python第三方库无比强大,PIL 是python的一个d第三方图片处理模块,我们也可以使 ...

  4. Java生成登陆时使用的图片验证码

    package com.ws.frame.utils; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; i ...

  5. java代码GUI简单的。。。

    总结:觉得 package com.da; import java.awt.*; //逆向思维:important //创建一个String对象的数组,然后执行读取文本,把文本每一行存入数组,它将读取 ...

  6. MVC伪一个12306图片验证码

    本文的来由主要是满足自己的好奇心,而不是证明什么东西,如果涉及到什么官方性的事情,麻烦通知我谢谢:本篇将要和大家分享的是一个看起来通12306图片验证码相似的效果,这篇应该是今年农历最后一篇分享文章了 ...

  7. 使用Maven根据WSDL生成生成Java代码

    转载:https://blog.csdn.net/pzasdq/article/details/52601473 为便于自己学习,整理 修改pom.xml <project xmlns=&quo ...

  8. 开发工具类API调用的代码示例合集:六位图片验证码生成、四位图片验证码生成、简单验证码识别等

    以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 六位图片验证码生成:包括纯数字.小写字母.大写字母.大小写混合.数 ...

  9. SpringBoot + Spring Security 学习笔记(三)实现图片验证码认证

    整体实现逻辑 前端在登录页面时,自动从后台获取最新的验证码图片 服务器接收获取生成验证码请求,生成验证码和对应的图片,图片响应回前端,验证码保存一份到服务器的 session 中 前端用户登录时携带当 ...

随机推荐

  1. dpdk环境配置

    1.配置流程 [1]修改/boot/grub2/grub.cfg,添加下列标记的配置项. linux16 /vmlinuz--.el7.x86_64 root=/dev/mapper/centos-r ...

  2. 刘志梅201771010115.《面向对象程序设计(java)》第十七周学习总结

    实验十七  线程同步控制 实验时间 2018-12-10 1.实验理论知识 多线程    多线程是进程执行过程中产生的多条执行线索.进程    线程是比进程执行更小的单位.线程不能独立存在,必须存在于 ...

  3. SQL JOIN 中 on 与 where 的区别

    left join : 左连接,返回左表中所有的记录以及右表中连接字段相等的记录. right join : 右连接,返回右表中所有的记录以及左表中连接字段相等的记录. inner join : 内连 ...

  4. Markdown 简单语法

    标题 文本前面加上 '#' 和一个空格 一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 加粗 文本两侧加上 '**' 加粗文本 斜体 文本两侧加上 '*' 斜体文本 斜体加粗 文本两侧加上 ...

  5. 树莓派3使用openSUSE Ports 42.3 驱动GPIO注意事项

    安装好opensuse 42.3以后,安装wiringPi库. 由于/proc/cpuinfo文件缺少“Hardware”信息,导致出现如下错误: Oops: Unable to determine ...

  6. leetcode1034

    class Solution: def __init__(self): self.V = list() def bfs(self,grid,color,rows,coloums,r,c,ocolor) ...

  7. Java初学者应该注意的学习问题

    作为初学者,在刚开始学习的时候,一定会走很多弯路.但其实很多弯路是不必走的,会浪费很多时间,导致学习效率大打折扣.今天小编给大家讲述一下,作为一个Java初学者,在开始学习的时候应该注意的问题,应该从 ...

  8. JAVA_maven 配置

    前人种树: https://www.cnblogs.com/supiaopiao/p/7276805.html?utm_source=itdadao&utm_medium=referral

  9. leetcode数据库题目及答案汇总

    1. 第二高的薪水 select ifnull((select distinct Salary from Employee order by Salary desc limit 1,1),null) ...

  10. es集群搭建

    1.复制5份es,版本要相同,且各个节点上jdk版本也要相同,否则会报数据同步格式不一致  invalid internal transport message format. 2.配置elastic ...