您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關如何使用canvas實現圖形驗證碼,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
細心的同學可以發現,現在很多網站當登錄多次之后就會出現一個圖形驗證碼,或是當提交表單、或點擊獲取手機驗證碼等等場景都會有圖形驗證碼的出現。
那么圖形驗證碼是為了解決什么問題而出現的呢?
圖形驗證碼是驗證碼的一種。驗證碼(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自動區分計算機和人類的圖靈測試)的縮寫,是一種區分用戶是計算機還是人的公共全自動程序。可以防止:惡意破解密碼、刷票、論壇灌水,有效防止某個黑客對某一個特定注冊用戶用特定程序暴力破解方式進行不斷的登陸嘗試,實際上用驗證碼是現在很多網站通行的方式。
既然圖形驗證碼是為了區分機器和人之間的操作,那么我們就可以在圖形上繪制一個只有人可以解答的問題。比較常見的是在圖片上生成文字驗證碼,然后用戶輸入圖片上的文字吻合則驗證通過。
雖然這種驗證方法已經漸漸的被其他更先進的方法所淘汰了(圖片上的文字依然可以被程序識別讀取),并且前端生成驗證碼的方式相較于后端安全性不高,但我們的目的只是為了裝x,提升程序的安全性只是附帶的效果。
首先我們需要在在登錄表單上額外添加用于輸入驗證碼的FormItem
,并且給圖形驗證碼提供一個canvas
容器。有時候生成的驗證碼看不明白,因此需要給驗證碼添加點擊事件用以切換驗證碼:
<Form ref="loginForm" :model="form" :rules="rules"> <FormItem prop="userName"> <Input v-model="form.userName" placeholder="請輸入用戶名"> <span slot="prepend"> <Icon :size="16" type="person"></Icon> </span> </Input> </FormItem> <FormItem prop="password"> <Input type="password" v-model="form.password" placeholder="請輸入密碼"> <span slot="prepend"> <Icon :size="14" type="locked"></Icon> </span> </Input> </FormItem> <FormItem prop="valiCode" v-show="this.count"> <Input v-model="form.valiCode" placeholder="請輸入驗證碼"> <span slot="prepend"> <Icon :size="14" type="ios-analytics"></Icon> </span> </Input> <div class="canvas" @click="getImgYanzheng"> <canvas id="canvas"></canvas> </div> </FormItem> <FormItem> <Button @click="handleSubmit" type="primary" long>登錄</Button> </FormItem> </Form>
表單需要額外添加valiCode
用以記錄用戶輸入的驗證碼。此處我們定義當用戶登錄失敗一次則需要額外輸入圖形驗證碼,因此添加count
屬性,當登陸失敗時count++
,當然這樣的處理方式并不是很嚴謹,并且用戶刷新頁面count
則會清零。可以在此處可以增加更多限制,如異地登錄等,由于本案例完全沒有涉及到后端程序,因此只是簡單的以count
為判斷依據。
data() { return { form: { userName: "",// 用戶名 password: "",// 密碼 valiCode: ""// 驗證碼 }, count: 0, // 登錄次數 show_num: [],// 圖形上的文字 } }
頁面上為canvas
容器綁定的方法getImgYanzheng
就是在繪制圖形驗證碼
。在繪制圖形驗證碼時需要為你的驗證碼定義一個內容集合,此處使用的是:A,B,C,E,F,G,H,J,K,M,N,P,Q,R,S,T,W,X,Y,Z,1,2,3,4,5,6,7,8,9,0,好,醫,生
。字母中剔除了容易誤識別的幾個字母并且可以隨意加入文字(因此圖形驗證碼也可在做成隨機生成四個文字讓用戶點擊,或者生成成語讓用戶填空等等各種形式)。并且忽略用戶大小寫,因此需要用到toLowerCase
方法。
接下來就是canvas
繪圖的一些技巧了。
canvas 元素本身是沒有繪圖能力的。所有的繪制工作必須在 JavaScript 內部完成:
var c=document.getElementById("myCanvas"); var cxt=c.getContext("2d");
在JavaScript 中使用 id 來尋找 canvas 元素,然后創建context對象,getContext("2d")
對象是內建的 HTML5 對象,擁有多種繪制路徑、矩形、圓形、字符以及添加圖像的方法。我們可以把canvas 想象成景色而context則是景色呈現的畫布。
由于繪制驗證碼的過程中是從左往右繪制的,因此需要規劃好畫布的使用范圍,另外在驗證碼繪制時還要加上一些隨機的元素使驗證碼不容易被程序識別。
getImgYanzheng() { var show_num = []; var canvas_width = 150; //document.getElementById("canvas").style.width; var canvas_height = 30; //document.getElementById("canvas").style.height; var canvas = document.getElementById("canvas"); //獲取到canvas的對象,景色 var context = canvas.getContext("2d"); //獲取到canvas畫圖的環境,景色呈現的畫布 canvas.width = canvas_width; canvas.height = canvas_height; var sCode = "A,B,C,E,F,G,H,J,K,M,N,P,Q,R,S,T,W,X,Y,Z,1,2,3,4,5,6,7,8,9,0,好,醫,生"; var aCode = sCode.split(","); var aLength = aCode.length; //獲取到數組的長度 for (var i = 0; i <= 3; i++) { var j = Math.floor(Math.random() * aLength); //獲取到隨機的索引值 var deg = (Math.random() * 30 * Math.PI) / 180; //產生0~30之間的隨機弧度 var txt = aCode[j]; //得到隨機的一個內容 show_num[i] = txt.toLowerCase(); var x = 10 + i * 20; //文字在canvas上的x坐標 var y = 20 + Math.random() * 8; //文字在canvas上的y坐標 context.font = "bold 23px 微軟雅黑"; context.translate(x, y); context.rotate(deg); context.fillStyle = this.randomColor(); context.fillText(txt, 0, 0); context.rotate(-deg); context.translate(-x, -y); } for (var i = 0; i <= 5; i++) { //驗證碼上顯示線條 context.strokeStyle = this.randomColor(); context.beginPath(); context.moveTo( Math.random() * canvas_width, Math.random() * canvas_height ); context.lineTo( Math.random() * canvas_width, Math.random() * canvas_height ); context.stroke(); } for (var i = 0; i <= 30; i++) { //驗證碼上顯示小點 context.strokeStyle = this.randomColor(); context.beginPath(); var x = Math.random() * canvas_width; var y = Math.random() * canvas_height; context.moveTo(x, y); context.lineTo(x + 1, y + 1); context.stroke(); } this.show_num = show_num; },
驗證碼及線條需要一些隨機的顏色:
randomColor() { //得到隨機的顏色值 var r = Math.floor(Math.random() * 256); var g = Math.floor(Math.random() * 256); var b = Math.floor(Math.random() * 256); return "rgb(" + r + "," + g + "," + b + ")"; }
有了以上兩個方法,圖形驗證碼就已經生成完畢了,接下來就是使用的問題了。
判斷登錄次數count
,如果登錄次數大于0則需要輸入驗證碼:
const self = this; if (this.count) { if (this.form.valiCode) { if (this.show_num.join("") != this.form.valiCode.toLowerCase()) { self.$Notice.warning({ title: "驗證碼錯誤" }); return; } } else { self.$Notice.warning({ title: "請輸入驗證碼" }); return; } }
當登錄失敗時需要執行count++
并且刷新驗證碼:
self.count++; self.getImgYanzheng(); self.$Notice.warning({ title: "登陸失敗", desc: rs.data.msg });
看完上述內容,你們對如何使用canvas實現圖形驗證碼有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。