Human-computer authentication
Adding human-machine authentication in some resource downloading and reading scenarios can prevent some simple network attacks. Only two native implementations are introduced.
canvas verification code
Draw specific text through canvas and mix it with lines and colors.
Rendering:
- verify.js
// verify.js 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: mixed type of numbers and letters, number: pure numbers, letter: pure letters code: "" } if (Object.prototype.toString.call(options) == "[object Object]") {<!-- -->// Determine the type of the incoming parameter for (var i in options) {<!-- --> // Modify the default parameter value based on the parameters passed in 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 the 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 generate font size ctx.fillStyle = randomColor(50, 160); // Randomly generate 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 the rotation angle and coordinate origin* */ ctx.rotate(-deg * Math.PI / 180); ctx.translate(-x, -y); } /** Draw interference lines* */ 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(); } }, /** Verify 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 an array of letters* */ 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 + ")"; } export default GVerify;
- Introduce verify.js into the component and initialize it (vue3)
<template> <div class="verify"> <p id="picyzm"/> <input type="text" v-model="inputCode" ref="inputRef" autofocus @keyup="startVerify"/> </div> </template> <script setup> import {<!-- --> ref, onMounted } from 'vue'; import GVerify from './verify'; const inputCode = ref(''); //Input box input content const verifyValue = ref(null); // Verification code object instance // Start verification const startVerify = () => {<!-- --> if(inputCode.value.length < 4) return; const res = verifyValue.value.validate(inputCode.value); if (res) {<!-- --> alert('Verification passed'); } verifyValue.value.refresh(); inputCode.value = ''; } onMounted(() => {<!-- --> verifyValue.value = new GVerify({<!-- --> id: "picyzm", // Area id for drawing verification code type: "blend" }); }) </script> <style lang='scss' scoped> .verify {<!-- --> display: flex; align-items: center; p {<!-- --> width: 100px; height: 30px; border: 1px solid #8b79ec; margin-right: 10px; } input {<!-- --> width: 80px; height: 30px; border-radius: 8px; border: 1px solid #ccc; outline: none; font-size: 12px; text-indent: 10px; letter-spacing: 2px; box-sizing: border-box; } } </style>
Image slider verification code
Different shapes are cut out by cutting out two identical canvases, one is cut into a puzzle piece, and the other is cut into a background without a puzzle piece, and then shifted.
When the user drags the slider, the two canvases are actually overlapped, and the puzzle will naturally align with the blank area of the background.
Rendering:
Contains image svg, etc., has been uploaded to the github warehouse