Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to generate Picture CAPTCHA with Vue

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces "Vue how to achieve picture CAPTCHA generation". In daily operation, I believe many people have doubts about how to achieve picture CAPTCHA generation in Vue. Xiaobian consulted all kinds of materials and sorted out simple and easy-to-use methods of operation. I hope it will be helpful to answer the doubts of "how to achieve picture CAPTCHA generation by Vue". Next, please follow the editor to study!

First, the generation of front-end image verification code

The front-end logic is basically to draw the graph, take a few random numbers into the picture, add interference, and verify.

1. Create a CAPTCHA component identify.vue

Export default {name: 'SIdentify', props: {identifyCode: {/ / default registration code type: String, default:' 1234'}, fontSizeMin: {/ / minimum font type: Number, default: 25}, fontSizeMax: {/ / font maximum type: Number, default: 35} BackgroundColorMin: {/ / CAPTCHA minimum background color type: Number, default: 200}, backgroundColorMax: {/ / CAPTCHA picture background color maximum type: Number, default: 220}, dotColorMin: {/ / minimum background interference point type: Number, default: 60} DotColorMax: {/ / background interference point maximum type: Number, default: 120}, contentWidth: {/ / container width type: Number, default: 117}, contentHeight: {/ / container height type: Number, default: 32}}, methods: {/ / generate a random number randomNum (min Max) {return Math.floor (Math.random () * (max-min) + min)}, / / generate a random color randomColor (min, max) {let r = this.randomNum (min, max) let g = this.randomNum (min, max) let b = this.randomNum (min, max) return 'rgb (' + r +','+ g +','+ b +')'} DrawPic () {let canvas = document.getElementById ('smurcanvasa') let ctx = canvas.getContext ('2d') ctx.textBaseline =' bottom' / / draw background ctx.fillStyle ='# e6ecfd' ctx.fillRect (0,0, this.contentWidth, this.contentHeight) / / draw text for (let I = 0 I

< this.identifyCode.length; i++) { this.drawText(ctx, this.identifyCode[i], i) } this.drawLine(ctx) this.drawDot(ctx) }, drawText (ctx, txt, i) { ctx.fillStyle = this.randomColor(50, 160) // 随机生成字体颜色 ctx.font = this.randomNum(this.fontSizeMin, this.fontSizeMax) + 'px SimHei' // 随机生成字体大小 let x = (i + 1) * (this.contentWidth / (this.identifyCode.length + 1)) let y = this.randomNum(this.fontSizeMax, this.contentHeight - 5) var deg = this.randomNum(-30, 30) // 修改坐标原点和旋转角度 ctx.translate(x, y) ctx.rotate(deg * Math.PI / 180) ctx.fillText(txt, 0, 0) // 恢复坐标原点和旋转角度 ctx.rotate(-deg * Math.PI / 180) ctx.translate(-x, -y) }, drawLine (ctx) { // 绘制干扰线 for (let i = 0; i < 4; i++) { ctx.strokeStyle = this.randomColor(100, 200) ctx.beginPath() ctx.moveTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight)) ctx.lineTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight)) ctx.stroke() } }, drawDot (ctx) { // 绘制干扰点 for (let i = 0; i < 30; i++) { ctx.fillStyle = this.randomColor(0, 255) ctx.beginPath() ctx.arc(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight), 1, 0, 2 * Math.PI) ctx.fill() } } }, watch: { identifyCode () { this.drawPic() } }, mounted () { this.drawPic() }} 2.父组件 前端生成验证码的校验是自己生成验证码,用户输入的值和生成的验证码字符串进行比对校验的,校验没有走后端,在真正发送请求到后端的时候也是不将验证码传给后台的。 提交 import Identify from "./identify";export default { name: "Reg", mixins: [region], components: {Identify }, data() { return { formSetting: { contentWidth: 340, }, form: { logoUrl: "", licenseUrl: "", description: [], account: "", name: "", }, code:this.$route.query.code, identifyCodes: "1234567890abcdefjhijklinopqrsduvwxyz", identifyCode: "", picList: [], props: { label: "name", value: "id", children: "children" }, rules: { code: [{ required: true, message: "请输入验证码", trigger: "change" }], }, formList: [], }; }, created() { // this.getAllDict() }, mounted() { this.getRegion(); // 初始化验证码 this.identifyCode = ""; this.makeCode(this.identifyCodes, 4); localStorage.setItem("code", this.code); }, methods: { openHtml() { this.visible = true; }, //刷新验证码 refreshCode() { this.identifyCode = ""; this.makeCode(this.identifyCodes, 4); }, //生成验证上的随机数,验证码中的数从identifyCodes中取, makeCode(o, l) { for (let i = 0; i < l; i++) { this.identifyCode += this.identifyCodes[ this.randomNum(0, this.identifyCodes.length) ]; } }, //生成随机数,这里是生成 //Math.random()方法返回大于等于0小于1的一个随机数 //随机数 = Math.floor(Math.random() * 可能的总数 + 第一个可能的值) randomNum(min, max) { return Math.floor(Math.random() * (max - min) + min); }, // 提交表单 submitForm() { this.$refs["form"].validate((valid) =>

{if (valid) {if (this.loading) {return;} this.loading = true; this.submit ();} else {return false;}}) }, submit: async function () {if (this.form.code.toLowerCase ()! = this.identifyCode.toLowerCase ()) {this.$msg ({type: "error", message: "Please fill in the correct verification code"}); this.refreshCode (); this.loading = false; return } else {/ / CAPTCHA verification succeeds, you can call the API to submit the form},},}; second, generate image CAPTCHA at the backend

Background idea is very, use BufferedImage class to create a picture, and then use Graphics to draw the picture (generate random characters, add noise, interference lines).

Package com.hengtiansoft.gxrc.base.util; import com.hengtiansoft.gxrc.common.constant.MagicNumConstant;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Component; import javax.imageio.ImageIO;import java.awt.Font;import java.awt.Color;import java.awt.Graphics;import java.awt.image.BufferedImage;import java.io.ByteArrayOutputStream;import java.util.Base64;import java.util.HashMap;import java.util.Map;import java.util.Random @ Slf4j@Componentpublic class ImgCaptchaUtil {private Random random = new Random (); / * the width of CAPTCHA * / private final int width = 160; the height of CAPTCHA * / private final int height = 40; the number of interference lines of CAPTCHA * / private final int lineSize = 30 / * CAPTCHA dictionary * / private final String randomString = "0123456789abcdefghijklmnopqrstuvwxyz"; / * get the font * @ return * / private Font getFont () {return new Font ("Times New Roman", Font.ROMAN_BASELINE, MagicNumConstant.FORTY) } / * get color * @ param fc * @ param bc * @ return * / private Color getRandomColor (int fc, int bc) {int fcc = Math.min (fc, MagicNumConstant.TWO_HUNDRED_FIFTY_FIVE); int bcc = Math.min (bc, MagicNumConstant.TWO_HUNDRED_FIFTY_FIVE); int r = fcc + random.nextInt (bcc-fcc-MagicNumConstant.SIXTEEN) Int g = fcc + random.nextInt (bcc-fcc-MagicNumConstant.FOURTEEN); int b = fcc + random.nextInt (bcc-fcc-MagicNumConstant.TWELVE); return new Color (r, g, b);} / * * draw interference lines * @ param g * / private void drawLine (Graphics g) {int x = random.nextInt (width); int y = random.nextInt (height) Int xl = random.nextInt (MagicNumConstant.TWENTY); int yl = random.nextInt (MagicNumConstant.TEN); g.drawLine (x, y, x + xl, y + yl);} / * * get random characters * @ param num * @ return * / private String getRandomString (int num) {int number = num > 0? Num: randomString.length (); return String.valueOf (randomString.charAt (random.nextInt (number);} / * * draw the string * @ param g * @ param randomStr * @ param I * @ return * / private String drawString (Graphics g, String randomStr, int I) {g.setFont (getFont ()) G.setColor (getRandomColor (MagicNumConstant.ONE_HUNDRED_EIGHT, MagicNumConstant.ONE_HUNDRED_NINETY)); String rand = getRandomString (random.nextInt (randomString.length (); String randomString = randomStr + rand; g.translate (random.nextInt (MagicNumConstant.THREE), random.nextInt (MagicNumConstant.SIX)); g.drawString (rand, MagicNumConstant.FORTY * I + MagicNumConstant.TEN, MagicNumConstant.TWENTY_FIVE); return randomString } / * generate random pictures and return the base64 string * @ param * @ return * / public Map getImgCodeBaseCode (int length) {Map result = new HashMap (); / / the BufferedImage class is the Image class with buffer, and the Image class is the class BufferedImage image = new BufferedImage (width, height, BufferedImage.TYPE_INT_BGR) used to describe image information. Graphics g = image.getGraphics (); g.fillRect (0,0, width, height); / / get color g.setColor (getRandomColor (MagicNumConstant.ONE_HUNDRED_FIVE, MagicNumConstant.ONE_HUNDRED_EIGHTY_NINE)); / / get font g.setFont (getFont ()); / / draw interference line for (int I = 0; I < lineSize) For +) {drawLine (g);} / / draw random characters String randomCode = ""; for (int I = 0; I < length; iTunes +) {randomCode = drawString (g, randomCode, I);} g.dispose (); result.put ("imgCode", randomCode); String base64Code = "" Try {/ / returns base64 ByteArrayOutputStream bos = new ByteArrayOutputStream (); ImageIO.write (image, "PNG", bos); byte [] bytes = bos.toByteArray (); Base64.Encoder encoder = Base64.getEncoder (); base64Code = encoder.encodeToString (bytes);} catch (Exception e) {log.debug (e.getMessage ()) } result.put ("data", _ "data:image/png;base64," + base64Code); return result;}}

The backend generates an image base64 and a unique key (which determines which image it is by this key). The backend can send the frontend image base64 and key through the API, input the verification code at the frontend, and pass it to the backend key and CAPTCHA to verify.

Package com.hengtiansoft.gxrc.base.service.impl; import com.hengtiansoft.gxrc.base.service.ImgCaptchaService;import com.hengtiansoft.gxrc.base.util.ImgCaptchaUtil;import com.hengtiansoft.gxrc.common.constant.MagicNumConstant;import com.hengtiansoft.gxrc.common.entity.exception.BusinessException;import com.hengtiansoft.gxrc.common.redis.RedisOperation;import com.hengtiansoft.gxrc.common.util.UUIDUtils;import org.apache.commons.lang3.ObjectUtils;import org.apache.commons.lang3.StringUtils;import org.springframework.beans.factory.annotation.Autowired Import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Service; import java.util.Map; / * * @ Description: * @ Author: wu * @ CreateDate: 17:17 * / @ Servicepublic class ImgCaptchaServiceImpl implements ImgCaptchaService {private static final String IMG_CAPTCHA = "imgCaptcha:" on 2020-11-11; @ Autowired private RedisTemplate redisTemplate; @ Autowired private ImgCaptchaUtil imgCaptchaUtil; @ Override public Map getImgCaptcha () {RedisOperation redisOperation = new RedisOperation (redisTemplate) Map map = imgCaptchaUtil.getImgCodeBaseCode (MagicNumConstant.FOUR); String uuid = UUIDUtils.createUUID (); redisOperation.set (IMG_CAPTCHA + uuid, map.get ("imgCode")); redisOperation.expire (IMG_CAPTCHA + uuid, MagicNumConstant.THIRTY_THOUSAND); map.remove ("imgCode"); map.put ("key", uuid); return map } @ Override public void checkImgCaptcha (String code, String key) {RedisOperation redisOperation = new RedisOperation (redisTemplate); String captcha = redisOperation.get (IMG_CAPTCHA + key); if (ObjectUtils.isEmpty (captcha) | |! StringUtils.equals (captcha, code) {throw new BusinessException ("CAPTCHA error");} redisOperation.del (IMG_CAPTCHA + key) }} at this point, the study on "how to achieve picture CAPTCHA generation by Vue" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report