驗證碼是一種人機驗證手段,用于防止惡意程序自動提交表單;文章提供了三種JS生成動態驗證碼的解決方案:1. 簡單隨機字符串驗證碼,適合安全性要求不高的場景;2. 帶簡單數學運算的驗證碼,安全性略高但仍可被ocr破解;3. 結合canvas的圖形驗證碼,安全性更高但用戶體驗稍差;此外,文章強調了必須結合后端驗證來防止驗證碼被繞過,并探討了驗證碼安全性與用戶體驗之間的平衡及其他生成驗證碼的方式。
驗證碼,簡單來說,就是一種人機驗證手段,防止惡意程序或機器人自動提交表單。JS生成動態驗證碼,意味著每次刷新或請求,驗證碼都會變化,增加了破解難度,提升了安全性。
直接上解決方案,從簡單的到復雜的,三種JS驗證碼生成算法,總有一款適合你:
解決方案
-
簡單隨機字符串驗證碼:
這是最基礎的,原理就是隨機生成一串字符,用戶輸入匹配就驗證通過。
function generateSimpleCaptcha(length) { let result = ''; const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; const charactersLength = characters.length; for ( let i = 0; i < length; i++ ) { result += characters.charAt(Math.floor(Math.random() * charactersLength)); } return result; } const captcha = generateSimpleCaptcha(6); // 生成6位驗證碼 console.log(captcha); // 輸出生成的驗證碼 // 驗證用戶輸入 function validateCaptcha(userInput, captcha) { return userInput === captcha; } // 示例 const userInput = prompt("請輸入驗證碼:" + captcha); if (validateCaptcha(userInput, captcha)) { alert("驗證成功!"); } else { alert("驗證失敗!"); }
這種方式簡單粗暴,容易被破解,適合對安全性要求不高的場景。
-
帶簡單數學運算的驗證碼:
稍微復雜一點,生成一個簡單的數學表達式,讓用戶計算結果。
function generateMathCaptcha() { const num1 = Math.floor(Math.random() * 10); const num2 = Math.floor(Math.random() * 10); const operators = ['+', '-', '*']; const operator = operators[Math.floor(Math.random() * operators.length)]; let answer; switch (operator) { case '+': answer = num1 + num2; break; case '-': answer = num1 - num2; break; case '*': answer = num1 * num2; break; } return { question: `${num1} ${operator} ${num2} = ?`, answer: answer.toString() // 注意轉換為字符串 }; } const captcha = generateMathCaptcha(); console.log(captcha.question); // 輸出問題 console.log(captcha.answer); // 輸出答案 // 驗證用戶輸入 function validateMathCaptcha(userInput, answer) { return userInput === answer; } // 示例 const userInput = prompt("請計算:" + captcha.question); if (validateMathCaptcha(userInput, captcha.answer)) { alert("驗證成功!"); } else { alert("驗證失敗!"); }
這種方式比純字符串稍微安全一點,但仍然可以通過OCR識別和簡單計算破解。
-
結合Canvas的圖形驗證碼:
利用Canvas繪制帶有干擾線的圖形驗證碼,增加破解難度。
function generateCanvasCaptcha(canvasId) { const canvas = document.getElementById(canvasId); const ctx = canvas.getContext('2d'); const width = canvas.width; const height = canvas.height; const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let captchaText = ''; // 生成隨機字符串 for (let i = 0; i < 4; i++) { captchaText += characters.charAt(Math.floor(Math.random() * characters.length)); } // 設置背景色 ctx.fillStyle = '#f0f0f0'; ctx.fillRect(0, 0, width, height); // 繪制文字 ctx.font = '20px Arial'; ctx.fillStyle = '#000'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(captchaText, width / 2, height / 2); // 繪制干擾線 for (let i = 0; i < 5; i++) { ctx.beginPath(); ctx.moveTo(Math.random() * width, Math.random() * height); ctx.lineTo(Math.random() * width, Math.random() * height); ctx.strokeStyle = '#ccc'; ctx.stroke(); } return captchaText; } // 使用示例 (HTML中需要有一個id為myCanvas的canvas元素) const captchaText = generateCanvasCaptcha('myCanvas'); console.log(captchaText); // 驗證用戶輸入 (需要從用戶輸入框獲取) function validateCanvasCaptcha(userInput, captchaText) { return userInput === captchaText; } // 示例 (假設userInput是用戶輸入的值) const userInput = prompt("請輸入圖片中的驗證碼:"); if (validateCanvasCaptcha(userInput, captchaText)) { alert("驗證成功!"); } else { alert("驗證失敗!"); }
這種方式安全性較高,但用戶體驗稍差,需要用戶識別圖片內容。可以增加字體扭曲、顏色變化等來進一步增強安全性。
如何防止JS驗證碼被繞過?
JS驗證碼本身存在一個問題:驗證邏輯在客戶端,容易被繞過。所以,僅僅依靠JS生成驗證碼是不夠的,必須結合后端驗證。
- 后端存儲驗證碼: 在生成驗證碼的同時,將驗證碼存儲在Session、redis等后端存儲中,并設置過期時間。
- 后端驗證: 用戶提交表單時,將用戶輸入的驗證碼和后端存儲的驗證碼進行比對。只有比對成功,才允許提交。
- 防止重放攻擊: 驗證成功后,立即銷毀后端存儲的驗證碼,防止重復提交。
驗證碼的安全性與用戶體驗如何平衡?
這是一個經典的問題。驗證碼越復雜,安全性越高,但用戶體驗越差。需要根據具體的應用場景進行權衡。
- 滑動驗證: 用戶只需要滑動滑塊到指定位置,操作簡單,安全性也較高。
- 點選驗證: 用戶需要點擊圖片中指定的物體,例如“點擊所有包含汽車的圖片”,安全性較高,用戶體驗也還不錯。
- 無感驗證: 通過分析用戶的行為特征,判斷是否為機器人。用戶無需進行任何操作,體驗最佳,但對算法要求較高。
除了JS,還有哪些生成驗證碼的方式?
- 后端生成: 后端生成驗證碼圖片,前端直接顯示。安全性較高,但需要后端配合。
- 使用第三方驗證碼服務: 例如Google reCAPTCHA、阿里云驗證碼等。這些服務通常提供多種驗證方式,安全性較高,但需要付費。
選擇哪種方式取決于你的具體需求和預算。如果對安全性要求不高,簡單的JS驗證碼也夠用。如果對安全性要求較高,建議使用后端生成或第三方驗證碼服務。
以上就是JS如何生成動態驗證碼 3種<a