The verification code on the website is generally placed on the login or registration page. Its role is to protect the security of websites. Generally, websites should use verification codes to prevent large-scale registration of machines, violent cracking of data passwords and other hazards.
Although the existence of verification code makes login a little more troublesome, this function is still necessary for website security.
When we use VFP Qiyou framework to develop BS website, we will also encounter such problems. Therefore, in order to ensure website security, we also need to add verification code to the web page we develop.
There are two ways to add verification codes on the website: front-end generation and front-end judgment; The backend generates backend judgments. Next, let's elaborate.
Library and tool Description:
Front end: vue+axios back end: VFP Qiyou three-tier development framework
The first method: generate the verification code at the front of the page and judge before submitting the data.


When submitting a Form, in order to prevent automatic program submission, a verification code is generally provided. It is used before the submit of the Form to detect whether the verification code is correct in advance. In this way, if the input verification code is consistent with the pre generated verification code, data submission is allowed, otherwise data submission is not allowed. In a certain program, it avoids the malicious submission of data by users and increases the burden of the server.
Implementation steps: when the page is loaded, the verification code image is loaded through the front-end JS. The following is the specific implementation core code.
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="./js/vue.min.js"></script> <script src="./js/axios.js"></script> <script src="./js/jsyzm.js"></script> <style type="text/css"> body,html {width: 100%;text-align: center;} #picyzm {width: 100px;height: 40px;display: inline;line-height: 40px;margin: 0 0 0 0px;} #code_input {width: 120px;height: 40px;display: inline;line-height: 40px;margin: 0 0 0 0px;font-size:24px;} #btn {margin: 0px;background-color: blue;color: #fff;border-radius: 5px;border: 0;width: 100px;height: 40px;dispaly:inline;} img{margin:0px;padding:0px;height: 40px;display: inline;line-height: 40px;cursor:hand;} </style> </head> <body> <!—Omitted here form Inside the user name and password part of the code --> <div id="app"> <input type="text" id="code_input" v-model:value="cYZM" placeholder="Enter the verification code in this box"> <div id="picyzm" ></div> <input type="button" value="verification" id="btn" v-on:click="toCX"> </div> <script> var vm = new Vue({ el: "#app", data: { cYZM: "", verifyCode:"" }, mounted:function(){ //Initialization verification code this.verifyCode = new GVerify({ id : "picyzm", type : "blend" }); }, methods: { toCX: function() { var res = this.verifyCode.validate(this.cYZM); if (!res){ alert('Verification code error') } else {alert(' Verification passed ')} }, } }) </script> </body> </html>
2 the JS code base (JSYZM.js) that generates the verification code does not rely on JQuery
Note the type that can be received by the type attribute of the options object (the default type of graphic verification code is blend: numeric alphabetic mixed type, number: pure number, letter: pure letter)
!(function(window, document) { function GVerify(options) { // Create a graphic verification code object and receive the options object as a parameter this.options = { // Default options parameter value id: "", // Container Id canvasId: "verifyCanvas", // ID of canvas width: "100", // Default canvas width height: "30", // Default canvas height type: "blend", // Default type of graphic verification code: blend type of numbers and letters, number: pure numbers, letter: pure letters code: "" } if(Object.prototype.toString.call(options) == "[object Object]"){// Judge the type of incoming parameter for(var i in options) { // Modify the default parameter value according to the passed in parameters this.options[i] = options[i]; } }else{ this.options.id = options; } this.options.numArr = "0,1,2,3,4,5,6,7,8,9".split(","); this.options.letterArr = getAllLetter(); this._init(); this.refresh(); } GVerify.prototype = { /** Version number* */ version: '1.0.0', /** Initialization method* */ _init: function() { var con = document.getElementById(this.options.id); var canvas = document.createElement("canvas"); this.options.width = con.offsetWidth > 0 ? con.offsetWidth : "100"; this.options.height = con.offsetHeight > 0 ? con.offsetHeight : "30"; canvas.id = this.options.canvasId; canvas.width = this.options.width; canvas.height = this.options.height; canvas.style.cursor = "pointer"; canvas.innerHTML = "Your browser version does not support canvas"; con.appendChild(canvas); var parent = this; canvas.onclick = function(){ parent.refresh(); } }, /** Generate verification code* */ refresh: function() { this.options.code = ""; var canvas = document.getElementById(this.options.canvasId); if(canvas.getContext) { var ctx = canvas.getContext('2d'); }else{ return; } ctx.textBaseline = "middle"; ctx.fillStyle = randomColor(180, 240); ctx.fillRect(0, 0, this.options.width, this.options.height); if(this.options.type == "blend") { // Determine verification code type var txtArr = this.options.numArr.concat(this.options.letterArr); } else if(this.options.type == "number") { var txtArr = this.options.numArr; } else { var txtArr = this.options.letterArr; } for(var i = 1; i <= 4; i++) { var txt = txtArr[randomNum(0, txtArr.length)]; this.options.code += txt; ctx.font = randomNum(this.options.height/2, this.options.height) + 'px SimHei'; // Randomly generated font size ctx.fillStyle = randomColor(50, 160); // Randomly generated font color ctx.shadowOffsetX = randomNum(-3, 3); ctx.shadowOffsetY = randomNum(-3, 3); ctx.shadowBlur = randomNum(-3, 3); ctx.shadowColor = "rgba(0, 0, 0, 0.3)"; var x = this.options.width / 5 * i; var y = this.options.height / 2; var deg = randomNum(-30, 30); /** Set the rotation angle and coordinate origin* */ ctx.translate(x, y); ctx.rotate(deg * Math.PI / 180); ctx.fillText(txt, 0, 0); /** Restore rotation angle and coordinate origin* */ ctx.rotate(-deg * Math.PI / 180); ctx.translate(-x, -y); } /** Draw interference line* */ for(var i = 0; i < 4; i++) { ctx.strokeStyle = randomColor(40, 180); ctx.beginPath(); ctx.moveTo(randomNum(0, this.options.width), randomNum(0, this.options.height)); ctx.lineTo(randomNum(0, this.options.width), randomNum(0, this.options.height)); ctx.stroke(); } /** Draw interference points* */ for(var i = 0; i < this.options.width/4; i++) { ctx.fillStyle = randomColor(0, 255); ctx.beginPath(); ctx.arc(randomNum(0, this.options.width), randomNum(0, this.options.height), 1, 0, 2 * Math.PI); ctx.fill(); } }, /** Verification code* */ validate: function(code){ var code = code.toLowerCase(); var v_code = this.options.code.toLowerCase(); if(code == v_code){ return true; }else{ return false; } } } /** Generate letter array* */ function getAllLetter() { var letterStr = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z"; return letterStr.split(","); } /** Generate a random number* */ function randomNum(min, max) { return Math.floor(Math.random() * (max - min) + min); } /** Generate a random color* */ function randomColor(min, max) { var r = randomNum(min, max); var g = randomNum(min, max); var b = randomNum(min, max); return "rgb(" + r + "," + g + "," + b + ")"; } window.GVerify = GVerify; })(window, document);
This verification code is generated in the front end and judged by the front end. It is concise and clear, but it has disadvantages. If you bypass the login page and directly initiate login detection, the verification code is invalid, and the server may still be maliciously attacked.
The second method: generate the verification code at the back end and display it at the front end. When submitting data, the back end breaks the verification code.
Implementation steps: render the front-end page, call the verification code image generated in the background, display it in the front-end, and submit it to the background for judgment. Note that this verification code has a problem of judging timeliness.

The code is as follows 1 web page file (login4.html)
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="./js/vue.min.js"></script> <script src="./js/axios.js"></script> <style type="text/css"> body,html {width: 100%;text-align: center;} #txt {display: inline; } #picyzm {width: 100px;height: 40px;display: inline;line-height: 40px;margin: 0 0 0 0px;} #code_input {width: 120px;height: 40px;display: inline;line-height: 40px;margin: 0 0 0 0px;font-size:24px;} #btn {margin: 0px;background-color: blue;color: #fff;border-radius: 5px;border: 0;width: 100px;height: 40px;dispaly:inline;} img{margin:0px;padding:0px;height: 40px;display: inline;line-height: 40px;cursor:hand;} </style> </head> <body> <div id="app"><div id="txt">Please enter the verification code:</div> <input type="text" id="code_input" v-model="cYZM" placeholder='' titlw="Enter verification code"> <img id="picyzm" v-bind:src="imgsrc" @click='changebmp' title='Click Replace verification code'> <input type="button" value="verification" id="btn" @click="toCX"> </div> </body> </html> <script> var vm = new Vue({ el: "#app", data: { yoururl:'http://192.168.0.105:801/', imgsrc: '', cYZM: '', verifyCode:'', imgcs: { // yzmstr: '', // yzmwidth: 4, // yzmheight: 1.2, // yzmfont: '', // yzmpath: '' }, }, mounted: function() { this.changebmp() }, methods: { toCX: function() { if(this.cYZM==null|| this.cYZM==''||this.cYZM==undefined){ alert(null) return } var that=this axios.get(that.$data.yoururl+'makeyzm.fsp?proc=checkyzm',{params:{key:that.$data.cYZM}}) .then(function(res){ alert(res.data) }) .catch(function(res){ alert(res.data) }) }, changebmp:function(){ var that = this; axios.get(that.$data.yoururl+'makeyzm.fsp',{params:{}}) .then(function(res) {that.$data.imgsrc = res.data }) .catch(function(res) {console.log('error:') console.log(res) }) } } }) </script>
2 VFP backend processing file (makeyzm.prg) It uses a lblAutoSize function to convert text into characters.
DEFINE CLASS makeyzm as session ***********following one two Action create a directory under the site directory yzmimg *********start of one ********* protected subpath subpath="yzmimg" *********end of one *********** *********start of two ********* PROCEDURE init LOCAL sp sp=getwwwrootpath(this.subpath) IF NOT DIRECTORY(sp) THEN mkdir("&sp") ENDIF ENDPROC *********end of two *********** ***********If there is a directory under the root directory of the website yzmimg Can be deleted two part PROCEDURE ondefault RETURN this.lblAutoSize() ENDPROC ***Save verification code PROCEDURE saveyzm PARAMETERS lyzm SELECT 0 USE zyzm APPEND BLANK REPLACE cyzm WITH lyzm REPLACE yzmdt WITH DATETIME() USE IN SELECT('zyzm') ENDPROC ***Verification code PROCEDURE checkyzm PRIVATE yzmtext,result yzmtext=httpqueryparams("key") ?"++++++++++++++++++++",yzmtext SELECT 0 USE zyzm LOCATE FOR ALLTRIM(cyzm)==ALLTRIM(yzmtext) AND (DATETIME()-yzmdt)/60<5 ?"------------",cyzm IF FOUND() result='Verification code input is correct' ELSE result='The verification period is expired or the verification code is entered incorrectly, please click the verification code to refresh' ENDIF USE IN SELECT('zyzm') RETURN result ENDPROC