Can programmers not install x? Give the login a graphics authentication code first! (canvas implementation)

Keywords: Programming Javascript Mobile less iOS

Careful students can find that many websites will appear a graphics authentication code after multiple logins, or when submitting forms, or clicking to obtain mobile phone authentication code and other scenarios will have graphics authentication code.

So what problems does Graphic Verification Code come up to solve?

What is Graphic Verification Code

Graphic verification code is a kind of verification code. CAPTCHA is "Completely Automated Public Turing test to tell Computers and Humans Apart" (fully automatic distinction between computers and humans). Turing test ) The abbreviation is a public automatic program that distinguishes whether a user is a computer or a person. Can prevent: malicious password cracking, ticket brushing, forum irrigation, effectively prevent a hacker to a specific registered user using specific procedures to violently crack the way of continuous landing attempts, in fact, the use of authentication code is the current way in many websites.

Since graphic validation codes are designed to distinguish between machine and human operations, we can draw a problem on the graph that only human can solve. It is more common to generate text validation codes on pictures, and then the user enters the text coincidence on the pictures and the validation passes.

Although this verification method has been gradually eliminated by other more advanced methods (the text on the picture can still be recognized and read by the program), and the front-end generation of verification codes is less secure than the back-end, but our purpose is only to install x, enhance the security of the program is only a side effect.

login form

First, we need to add an additional FormItem to the login form for input validation codes, and provide a canvas container for graphical validation codes. Sometimes the generated validation code can't be seen clearly, so click events need to be added to the validation code to switch the validation code:

<Form ref="loginForm" :model="form" :rules="rules">
    <FormItem prop="userName">
        <Input v-model="form.userName" placeholder="enter one user name">
            <span slot="prepend">
                <Icon :size="16" type="person"></Icon>
            </span>
        </Input>
    </FormItem>
    <FormItem prop="password">
        <Input type="password" v-model="form.password" placeholder="Please input a password">
            <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="Please enter the verification code.">
            <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>Sign in</Button>
    </FormItem>
</Form>

Attributes to be used

The form requires additional valiCode to record the authentication code entered by the user. Here we define that when a user fails to log in once, additional graphical authentication codes are needed, so add count attribute, count ++ when the login fails, of course, this is not very rigorous, and the user refreshes the page count will be cleared. More restrictions can be added here, such as remote login, because this case does not involve the back-end program at all, so it is simply based on count.

data() {
    return {
      form: {
        userName: "",// User name
        password: "",// Password
        valiCode: ""// Verification Code
      },
      count: 0, // Number of logins
      show_num: [],// Graphical text
    }
}

Production Graphics Verification Code

The method getImgYanzheng, which binds canvas containers on the page, is drawing graphical verification codes.

. When drawing graphic verification codes, you need to define a content set for your verification codes. Here you use: 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, good, medical, health. Several letters which are easy to be misidentified are removed from the letters and text can be added at will (so the graphics validation code can also be made into four randomly generated words for users to click on, or generate idioms for users to fill in the blanks, etc.). And ignoring user case, we need to use the toLowerCase method.

Next are some techniques of canvas drawing.

canvas drawing

The canvas element itself is not capable of drawing. All drawing must be done within JavaScript:

var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");

Use id in JavaScript to find canvas elements, and then create context objects, getContext("2d") objects are built-in HTML5 objects, with a variety of drawing paths, rectangles, circles, characters and adding images. We can imagine canvas as a landscape and context as a canvas of the landscape.

Because the process of drawing validation code is from left to right, it is necessary to plan the scope of use of the canvas. In addition, some random elements are added to the drawing of validation code to make it difficult for the validation code to be recognized by the program.

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"); //Get the object, scene of canvas
      var context = canvas.getContext("2d"); //Get the canvas drawing environment, the canvas of the scene presentation
      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,good,medicine,living";
      var aCode = sCode.split(",");
      var aLength = aCode.length; //Gets the length of the array

      for (var i = 0; i <= 3; i++) {
        var j = Math.floor(Math.random() * aLength); //Get random index values
        var deg = (Math.random() * 30 * Math.PI) / 180; //Generate random radians between 0 and 30
        var txt = aCode[j]; //Get a random content
        show_num[i] = txt.toLowerCase();
        var x = 10 + i * 20; //x coordinates of text on canvas
        var y = 20 + Math.random() * 8; //y coordinates of text on canvas
        context.font = "bold 23px Microsoft YaHei";

        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++) {
        //Verification Code Displays Lines
        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++) {
        //Small dots on the verification code
        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;
    },

Verification codes and lines need some random colors:

randomColor() {
      //Get random color values
      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 + ")";
    }

With the above two methods, the graphics verification code has been generated, and then the use of the problem.

Using Graphic Verification Code

Determine the number of logins count, if the number of logins is greater than 0, you need to enter a validation code:

const self = this;
if (this.count) {
		if (this.form.valiCode) {
			if (this.show_num.join("") != this.form.valiCode.toLowerCase()) {
				self.$Notice.warning({
					title: "Verification code error"
				});
				return;
			}
		} else {
			self.$Notice.warning({
				title: "Please enter the verification code."
			});
			return;
		}
	}

When the login fails, count++ needs to be executed and the authentication code refreshed:

self.count++;
self.getImgYanzheng();
self.$Notice.warning({
title: "Landing Failure",
desc: rs.data.msg
});

At this time, we have finished adding a graphics verification code. Let's pack it up quickly. Re-evaluation is the greatest encouragement

Posted by psyickphuk on Mon, 09 Sep 2019 00:20:20 -0700