Pre-code download

Github.com/18888628835…

preface

When we log in to a web page, as long as the input account password, if the account password is the same as when registering, then it will prompt login success and jump to the page, if the failure will prompt failure. So, what data conversion has taken place from user registration to login, and how does the interaction between the front and back end occur? This is the problem I want to describe today. This blog is a record of simulating small functions of user login, and I will repeat what I have learned here.

Before I started, I had to use JSON files as my database for device reasons, and everything revolved around JSON files.

The whole page jump process looks like this: Register — login– home page index

Our preferred goal is to set a small target and simulate a registration function first

Registration procedure

  • We need to write a registration page

  • Use jquery ajax to transfer data to the back end

  • The back end receives the data and uses Node.js to process it

  • Put the data into a JSON file

Of course, before doing this, we need to write the basic code of the static server, which can be viewed in the pre-code.

The preparatory work

  • Three HTML pages: login, registration and home page respectively
  • A server written in simple Node.js
  • A JSON file named mysql is used as the database

The pre-work code is in the init folder of the pre-code download

The registration page uses Ajax

How to create a form form is not explained here, here is ajax jquery code for further explanation

const $form = $('form') $form.on('submit', (e) => {e.preventDefault() const userId = $form.find('input[name=userid]').val( $form.find('input[name=password]').val() $.ajax({url: './registered', method: 'POST', contentType: "text/json; Charset = utF-8 ", data: json.stringify ({// must convert to a JSON string before passinguserId: userid, password: password})})Copy the code

Jquery’s Ajax wrapper is called when the form triggers a Submit event. Since the default behavior when submitting the form is to refresh the page, we first block the default behavior with e.preventDefault(), and then pass an object with jquery’s Ajax wrapper. Note that it is important to use json.stringfy () to pass the user-written value, because if I do not do this, I will never get the pass encoding right when I write the back-end code.

Write to the server node.js

We can use the Request. on(‘data’,()=>{}) event to retrieve JSON data passed by AJAX. Since bytes may be passed in segments, we use a [] array to prevent data being passed

Const ajaxData = [] request.on('data', (data) => {ajaxdata.push(data) //Copy the code

Then use the request.on(‘end’,()=>{}) event to receive all the downloaded code

Query the contents of the JSON file

// Node reads data from a JSON file

Const fs = require('fs') // const data = fs.readfilesync ('./mysql.json') // const mysql = json.parse (data)Copy the code

Turn ajax data into objects

Const jsonData = json.parse (string) const string = buffer.concat (ajaxData).toString()Copy the code

Write data to a file

const newdata = {
   	id: id,
    userid: jsondata.userid,
    password: jsondata.password
                }
    mysql.push(newdata)
    fs.writeFileSync('./mysql.json', JSON.stringify(mysql))
Copy the code

Id value

Since all data tables in the database always follow an absolutely unique code, after we get the Ajax data and process it, we need to give an ID and save it to the file along with the ajax data we get

let id = mysql[mysql.length - 1] ? (mysql[mysql.length-1]. Id +1) : 1; (mysql[mysql.length-1]Copy the code

The registration page writes functions that ajax passes successfully

As the Ajax standard uses promise objects, the. Then () function can be used. When ajax succeeds, the promise object itself will be fulfilled, then the first function parameter of the THEN function will be called, with the code as follows

.then(()=>{ location.href='./login.html' })

At this point, the registration function is basically complete.

The login

The operation during login is almost the same as the code during registration, including the AJAX code. We only need to change the registration in the form form to login, and the code after AJAX success is changed to jump to index.html after success, and the account password error message is displayed if failure.

The location.assign() method is introduced here to jump to the page, because if you use location.href to jump to the page, you might not be able to jump to the prompt box.

location.assign('./index.html')
Copy the code

Server code

We just need to verify that the ajax data submitted is the same as the json file, using the array.prototype. find method

This method returns the value of the first element in the array that satisfies the provided test function. Otherwise return undefined.

The code is as follows:

If (path === '/public/login.html' && request.method === 'POST') {let arr = []// request. On ('data', (data) => { arr.push(data) }) request.on('end', () => { const arrdata = JSON.parse(arr) response.setHeader('Content-type', 'text/html; charset=UTF-8') let sql = JSON.parse(fs.readFileSync('./mysql.json')) const n = sql.find((val) => { return val.password Userid === arrData.password && val.userId === arrdata.userId}) //find the return value if (n === undefined) {response.statusCode = 400 } else {response.statuscode = 200} response.end(' send ')})Copy the code

The above code uses the find method to determine if the value is undefined. If it is, the corresponding data cannot be found in the JSON file, and the front end returns “jump failed”.

Login complete, set a small goal

Registration to login has been completed, now if the verification is successful should jump to the home page. Now I have a new requirement, when I log in and go to the home page, let the home page show that the user is logged in.

But at this time encountered a problem, how to let the server know that I was logged into the home page or not logged into the home page? The difference between the two is that after login, the home page prompts the user to log in, and if not, the home page is in the original state

Enter the home page

cookie

In real life, if we want to enter a charging park, then someone will check the ticket, this ticket is the proof that you have not charged, so the demand above, is similar to this?

Assuming that the user has logged in, the server sends a ticket to the user, so is it possible to achieve the login page and not logged in inconsistent situation?

This ticket is a cookie, it is saved by the browser, we can use the server code to successfully log in to the user to send a cookie, how to set? We set it in the HTTP response header

When the user clicks login, we give this cookie to the user, set-cookie MDN

Note that cookies need to be set by the back-end code and set to not allow the front-end to modify the syntax:

response.setHeader('Set-Cookie', 'xxx=xxx; HttpOnly')Copy the code

However, cookie has a disadvantage, that is, even if the written cookie cannot be tampered with, it can still be modified through the Application of the browser. After tampering, it is equivalent to getting the ticket. Then, if it happens to be the cookie of other users, it is equivalent to getting other users’ data, right?

So how do you solve this security problem?

The session session

In fact, this problem is nothing more than the value of the cookie value problem, if the cookie is enough random digits, then even if the cookie is not modified, because it does not match other users.

So we can solve it like this:

Create a JSON file session. JSON to store the random number and make the random number correspond to the user ID. As long as the cookie is the random number, the user information corresponding to the ID will be sent out.

This method has a fancy name called session

So our design process should be like this:

  • First, the user logs on to the home page
  • We check the user’s cookie for the specified cookie
  • If not, go to the default home page
  • If so, we’ll change the default home page username

The data flow should look like this: if the user’s cookie is obtained, then make a judgment to see if it can be found in session.json. If it can be found, then it does represent the target customer, and we take the id of the corresponding target user

So what can we put inside session.json? {” random number “, {id: XXX}}

Login code is perfect

const n = sql.find((val) => { return val.password === arrdata.password && val.userid === arrdata.userid }) // Check whether the login account and password are the same. If (n === undefined) {// If (n === undefined) {// If (n === undefined) {return code 400 response.statusCode = 400} else {response.statusCode = 200 const Parse (fs.readfilesync ('./session.json')) // Read the new session file const random = math.random () // Set a random number session[random] = { 'userid': Fs.writefilesync ('./session.json', json.stringify (session)) // return the cookie to the user with the random number. Responsetheader (' set-cookie ', 'sessionId =${random}; HttpOnly`) }Copy the code

In the code above, I set a random number cookie to the user, which is equivalent to the cookie is a string of very long keys. As long as the user enters the home page, check whether there is this cookie, and then check whether the cookie is correct

The home page code

if (path === '/index.html') { response.statusCode = 200 response.setHeader('Content-type', 'text/html; Parse (fs.readfilesync ('./mysql.json')) charset= utF-8 ') let cookie = request. Parse (fs.readfilesync ('./session.json')) let sessionId try {sessionID  = cookie.split('; ').filter(s => s.idexof (" sessionId =") >= 0)[0].split("=")[1] If (sessionId) {// If (sessionid) {// If (sessionid) { Let user = mysql.find((user) => {return user.id === session[sessionId].userId}) let string = "if String = fs.readfilesync ('./public/index.html').toString().replace('{{username}}', Response.write (string)} else {response.write(fs.readfilesync ('./public/index.html')}} else {response.write(fs.readfilesync ('./public/index.html')}} else { response.write(fs.readFileSync('./public/index.html')) } response.end()Copy the code

Stern said

The above code is just a crude description of some of the problems and solutions that exist in front and back end interaction. In the actual development process, we will encounter more complex, more safety related problems, and deepen our understanding and awe of the program as we constantly modify the logic through trial and error.