SpringBoot+Vue项目中实现登录验证码校验

SpringBoot+Vue项目中实现登录验证码校验

在各大项目中,为保证数据的安全性,通常在登录页面加入验证码校验,以防止爬虫带来的数据泄露危机。本文将介绍在前后端分离的项目中,怎样实现图形验证码校验。

实现思路

第一步:在后端创建一个生成随机验证码的工具类和接收请求验证码的接口。工具类的主要作用生成随机验证码和对应的图片。接口的作用是将生成的随机验证码保存到session,同时,将图片进行base64编码,然后返回给前端。

第二步:在登录页面创建的同时获取验证码,并将后端传回来得key和编码后的字符串拼接,绑定img标签的src属性。此外,当用户点击验证码的img标签时,重新获取验证码,后端session更新验证码。

第三步:后端登录接口接收登录请求时,将用户提交的验证码和session中的验证码进行比对,不相同则返回相应信息给前端进行提示,相同则进行账号密码的匹配。

测试案例

  • 创建验证码生成的工具类

package com.check.utils;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.image.BufferedImage;import java.io.IOException;import java.io.OutputStream;import java.util.Random;import javax.imageio.ImageIO;public class CreateImageCode { // 图片的宽度。 private int width = 160; // 图片的高度。 private int height = 40; // 验证码字符个数 private int codeCount = 4; // 验证码干扰线数 private int lineCount = 20; // 验证码 private String code = null; // 验证码图片Buffer private BufferedImage buffImg = null; Random random = new Random(); public CreateImageCode() { creatImage(); } public CreateImageCode(int width, int height) { this.width = width; this.height = height; creatImage(); } public CreateImageCode(int width, int height, int codeCount) { this.width = width; this.height = height; this.codeCount = codeCount; creatImage(); } public CreateImageCode(int width, int height, int codeCount, int lineCount) { this.width = width; this.height = height; this.codeCount = codeCount; this.lineCount = lineCount; creatImage(); } // 生成图片 private void creatImage() { int fontWidth = width / codeCount;// 字体的宽度 int fontHeight = height – 5;// 字体的高度 int codeY = height – 8; // 图像buffer buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = buffImg.getGraphics(); //Graphics2D g = buffImg.createGraphics(); // 设置背景色 g.setColor(getRandColor(200, 250)); g.fillRect(0, 0, width, height); // 设置字体 //Font font1 = getFont(fontHeight); Font font = new Font(“Fixedsys”, Font.BOLD, fontHeight); g.setFont(font); // 设置干扰线 for (int i = 0; i < lineCount; i++) { int xs = random.nextInt(width); int ys = random.nextInt(height); int xe = xs + random.nextInt(width); int ye = ys + random.nextInt(height); g.setColor(getRandColor(1, 255)); g.drawLine(xs, ys, xe, ye); } // 添加噪点 float yawpRate = 0.01f;// 噪声率 int area = (int) (yawpRate * width * height); for (int i = 0; i < area; i++) { int x = random.nextInt(width); int y = random.nextInt(height); buffImg.setRGB(x, y, random.nextInt(255)); } String str1 = randomStr(codeCount);// 得到随机字符 this.code = str1; for (int i = 0; i 255) bc = 255; int r = fc + random.nextInt(bc – fc); int g = fc + random.nextInt(bc – fc); int b = fc + random.nextInt(bc – fc); return new Color(r, g, b); } /** * 产生随机字体 */ private Font getFont(int size) { Random random = new Random(); Font font[] = new Font[5]; font[0] = new Font(“Ravie”, Font.PLAIN, size); font[1] = new Font(“Antique Olive Compact”, Font.PLAIN, size); font[2] = new Font(“Fixedsys”, Font.PLAIN, size); font[3] = new Font(“Wide Latin”, Font.PLAIN, size); font[4] = new Font(“Gill Sans Ultra Bold”, Font.PLAIN, size); return font[random.nextInt(5)]; } // 扭曲方法 private void shear(Graphics g, int w1, int h1, Color color) { shearX(g, w1, h1, color); shearY(g, w1, h1, color); } private void shearX(Graphics g, int w1, int h1, Color color) { int period = random.nextInt(2); boolean borderGap = true; int frames = 1; int phase = random.nextInt(2); for (int i = 0; i > 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames); g.copyArea(0, i, w1, 1, (int) d, 0); if (borderGap) { g.setColor(color); g.drawLine((int) d, i, 0, i); g.drawLine((int) d + w1, i, w1, i); } } } private void shearY(Graphics g, int w1, int h1, Color color) { int period = random.nextInt(40) + 10; // 50; boolean borderGap = true; int frames = 20; int phase = 7; for (int i = 0; i > 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames); g.copyArea(i, 0, 1, h1, 0, (int) d); if (borderGap) { g.setColor(color); g.drawLine(i, (int) d, i, 0); g.drawLine(i, (int) d + h1, i, h1); } } } public void write(OutputStream sos) throws IOException { ImageIO.write(buffImg, “png”, sos); sos.close(); } public BufferedImage getBuffImg() { return buffImg; } public String getCode() { return code.toLowerCase(); }}

  • 编写获取验证码的接口

@RequestMapping(“/login”)@RestControllerpublic class LoginController { @GetMapping(“/getImage”) public Result getImage(HttpServletRequest request) throws IOException { Map result = new HashMap(); CreateImageCode createImageCode = new CreateImageCode(); //获取验证码 String securityCode = createImageCode.getCode(); //验证码存入session String key = new SimpleDateFormat(“yyyyMMddHHmmss”).format(new Date()); request.getServletContext().setAttribute(key, securityCode); //生成图片 BufferedImage image = createImageCode.getBuffImg(); //进行base64编码 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ImageIO.write(image, “png”, bos); String string = Base64Utils.encodeToString(bos.toByteArray()); result.put(“key”, key); result.put(“image”, string); return ResultUtils.success(“请求成功”,result); }}

  • 编写axios请求验证码的函数

import requests from “./request”;export const GetImage=()=>requests({ url: “/login/getImage”, method: “get”})

  • vuex中编写异步方法

import {GetImage} from ‘../api/login’const state={};const mutations={};const actions={ async getImage(){ let result=await GetImage().then(); return result.dataset; }};const getters={};export default{ state, mutations, actions, getters}

  • 将验证码绑定给img的src

async getimage() { let result = await this.$store.dispatch(“getImage”); this.imageurl = “data:image/png;base64,” + result.image; this.adminInfo.key = result.key; },

  • 编写登录接口

@PostMapping(“/login”) public Result login(@RequestBody Login login, HttpServletRequest request){ System.out.println(login); String keyCode = (String) request.getServletContext().getAttribute(login.getKey()); if(keyCode.equals(login.getCode().toLowerCase())){ Admin admin = new Admin(); admin.setUsername(login.getUsername()); admin.setPassword(login.getPassword()); Admin admin1 = adminService.login(admin); if(admin1!=null){ return ResultUtils.success(“登录成功”,admin1); }else { return ResultUtils.error(“账号或密码错误!”); } }else { return ResultUtils.error(“验证码错误!”); }

测试结果

  • 前端页面
  • 输入错误验证码
郑重声明:本文内容及图片均整理自互联网,不代表本站立场,版权归原作者所有,如有侵权请联系管理员(admin#wlmqw.com)删除。
(0)
用户投稿
上一篇 2022年7月10日
下一篇 2022年7月10日

相关推荐

  • 美甲|冰透系显白美甲

    又奶又糯的冰透感美甲了啦!!! 希望里面有小姐姐中意的款式哟!!! 喜欢的可以点个关注[送心] 后续会有更多美甲推送哟! 图片来源于网络,侵删

    2022年7月21日
  • 「夏日乐游副中心」强推宋庄艺术区这10大宝藏空间!周末打卡好去处

    宋庄是大运河文化带上的一颗艺术明珠,这里生活着近万名艺术家,百余家民营美术馆和艺术机构星罗棋布,其中3000平方米以上的美术馆就有多达35家。近年来,宋庄努力打造具有国际影响力的艺…

    2022年8月11日
  • 4600元 i5-12400F+3060 12G 这个配置亏不亏?

    4600拿下这一套配置,不能算是坑,毕竟光盈通RTX3060-12G D6 大地之神,这一张显卡,狗东价格都在2599-2699呢!i5-12400F,单买的话,现在也得1399元…

    2022年8月10日
  • 图片报:纳帅或连续3场首发相同 马内穆西亚拉加练&萨内打卡下班

    直播吧8月11日讯 《图片报》消息,拜仁正在备战对阵狼堡的德甲第二轮比赛,纳帅在训练课上沿用了上两场的首发阵容。 拜仁在前2场正式比赛狂轰11球,进攻端的所有首发球员都表现出色:马…

    2022年8月11日
  • 基于SpringBoot的ERP系统,自带进销存+财务+生产功能

    这个ERP基于SpringBoot框架和SaaS模式,立志为中小企业提供开源好用的ERP软件,目前专注进销存+财务+生产功能。主要模块有零售管理、采购管理、销售管理、仓库管理、财务…

    2022年6月14日
  • 来日方长意思是什么(来日方长完整句子)

    人们往往用来日方长安慰急于谋事,而又一事无成的自己,也去安慰那些急于建功立业,而又征途坎坷的别人。 网络图片 来日方长意思是:未来的日子还很长,表示事还有回旋余地,还有可为的机会,…

    2022年4月20日
  • 安徽:新能源和节能环保产业规模不断扩大

    随着“双碳”目标提出,安徽省新能源和节能环保产业整体呈现活力增强、快速发展的态势。今年上半年,全省新能源和节能环保产业总产值同比增长25.6%,规模以上企业1323家。以“双招双引…

    2022年8月16日
  • 德国国脚涉嫌殴打怀孕女友,最高可获刑10年

    德国《图片报》日前披露:多特蒙德后卫尼科·舒尔茨在6月被前女友指控家暴,警方已经完成搜证工作,多特蒙德检察院正在进行调查。 前女友J提供了长达76页的聊天记录、图片等证据,指控舒尔…

    2022年8月8日
  • 顺义区京北智慧物流园取得征地批复

    本报讯 北青报记者从顺义区获悉,京北(大孙各庄)智慧物流园项目正在有序推进中,目前已取得征地批复。据了解,该项目预计投资约30.5亿元,规划总用地面积约71.66公顷,建筑规模约5…

    2022年6月28日
  • 发现最近头条,很多买了车,然后要拍几十个视频,这是什么心态?

    炫耀啊,还能是什么心态搞的好像都没见过车一样真正低调的人从来都不会到处炫耀,说句不好听的现在有些人就是喜欢装车就是一个代步工具其实也没什么,还有的要么炫耀要么炫富 炫耀呗,还能咋滴…

    2022年7月26日

联系我们

联系邮箱:admin#wlmqw.com
工作时间:周一至周五,10:30-18:30,节假日休息