Complete process of login and registration

Time:2021-4-26

Development Scenario Description:

When you are ready to start a project from scratch, the front and back platforms are developing at the same time. Because the background may not be able to provide data due to time problems, you need front-end personnel to simulate data, such as mock. In the external Vue, mock operation can also be implemented to simulate data.
You need to have a certain understanding of JWT (JSON web token) and token.
·First, open Apache and mysql

Implementation of login part

  1. Step 1: build the basic project framework of Vue, install NPMI — save Axios on the front end, and create a login page, login
<template>
  <div>
    Account number: < input type = "text" placeholder = "account number" V-model = "user name" >
    Password: < input type = text "placeholder = password" V-model = password ">
    < button @ Click = "mylogin" > login < / button >
  </div>
</template>
<script>
export default {
    data(){
        return{
            username:"",
            password:""
        }
    },
    methods:{
        myLogin(){
           //Login process
        }
    }
}
</script>
  1. Step 2: introduce login into routing and configure it
  2. Step 3: simulate background data with mock, create a mock folder in the root directory of the project, open the terminal, install NPMI — save express Axios, and create two files under mock index.js And router.js
index.js file
const express = require("express");
const app = express();
const router = require("./router")
const bodyParser = require("body-parser");

app.use(bodyParser.urlencoded({
    extended:true
}))

app.use("/api",router)

app.listen(3000,() =>{
    console.log ("server running on port 3000");
})
router.js file
const express = require("express");
const router = express.Router();

router.post('/login',(req,res)=>{
    const username = req.body.username;
    const password = req.body.password;
    if(username && password){
        res.send({
            MSG: "login succeeded",
            code:200
        })
    }else{
        res.send({
            MSG: "login failed,",
            code:400
        })
    }
})

module.exports = router;
  1. First use postman to test, which is easy to be the front-end error or the background error. If you can get success, then execute the next step
  2. Go back to the foreground, create utils folder, and create it inside request.js And configure
//Encapsulating network requests: Axios

import axios from "axios"
import qs from "query-string"

//Response method of error message
const errorHandle = (status,other) => {
    switch(status){
        case 400:
            //Request header and server restrictions
            console.log ("the server does not understand the syntax of the request");
            break;
        case 401:
            //Token authentication failed, user authentication failed
            console.log ("(unauthorized) request requires authentication));
            break;
        case 403:
            //The user's identity has expired and the server's request is restricted
            console.log ("(prohibit) the server from rejecting the request");
            break;
        case 404:
            //Network request address error
            console.log ("(not found) the server could not find the requested page.");
            break;
        default:
            console.log(other);
            break;
            
    }
}

//Creating Axios objects
const instance = axios.create({
    timeout:5000  //  request timeout
})

//Global configuration
instance.defaults.baseUrl = "http://iwenwiki.com";
// instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

//Create request interception and response interception operations
instance.interceptors.request.use(config =>{
        //Configuration
        if(config.method === 'post'){
            config.data = qs.stringify(config.data);
        }
        return config;
    },
    error => Promise.reject(error)
)

instance.interceptors.response.use(
    //Success 
    /**
     *Judgment of success and failure:
     *1. Request success and request failure
     *2. Request success: the success of the result and the failure of the result
     * 
     *Really good code:
     *1. High readability
     *2. Strong maintainability
     *Not the code of daily account!!!
     *Object oriented thinking mode: OOP
     */
    response => response.status === 200 ? Promise.resolve(response) : Promise.reject(response),
    //We encapsulate it ourselves, so in order to make the code clear and readable, we need to add promise
    // response => response,
    error => {
        const { response } = error; //  Deconstruction assignment of ES6
        /**
         *The response contains the following information:
         *  status
         *  data
         */
        if(response){
            //Give the developer specific error information
            errorHandle(response.status,response.data);
            return Promise.reject(response);
        }else{
            console.log ("request interrupted or disconnected");
        }
    }
)

export default instance;

Then create an API folder, which is created separately base.js It is used to store the path; index.js To store encapsulated network requests

// base.js file
const base = {
    baseUrl:'/api',
    login:'/api/login'
}

export default base;
// index.js file
import base from './base'
import axios from '../utils/request'

const api = {
    //Login interface
    getLogin(params){
       return axios.post(base.baseUrl + base.login,params)
    }
}

export default api;
  1. To solve the cross domain problem: create a vue.config.js Configure file and set configuration item:
// vue.config.js file
module.exports = {
    devServer:{
        proxy:{
            "/api":{
                target:"http://localhost:3000/",
                Pathrewrite: {// rewrite path
                    "^/api":""
                },
                changeO rigin:true  // Allow cross domain
            }
        }
    }
}
  1. Getting data in the login component
methods:{
        myLogin(){
           this.$api.getLogin({
               username:this.username,
               password:this.password
           }).then(res=>{
               console.log(res);
           }) 
        }
    }

Implementation of login verification part

Scenario: Click to enter the about page to verify whether the user logs in. If the login is successful, the user can enter the about page. If the user does not log in or the login is unsuccessful, the user will automatically jump to the login page. Here are two knowledge points: token and JWT (JSON web token)

  1. Step 1: set the routing meta information for the about component.
{
    path: '/about',
    name: 'About',
    meta:{
      isLogin:true
    },
    component: () => import('../views/About.vue')
 }
  1. Step 2: generate the token in the background. Create one in the mock file config.js And configure
module.exports = {
    jwtSecret:"somesecrtekeyforjsonwebtoken"  
    //The real project is responsible for the back office
}
  1. Step 3: configure routing in the background. Install NPMI — save JSON webtoken in the background and router.js Medium configuration
const config = require("./config");
const jwt = require("jsonwebtoken");
//Generate token
const token = jwt.sign({
                username: username,
                password: password
            }, config.jwtSecret);
res.send({
        ...
        token:token,
        username:username
    })
  1. Step 4: at this time, the foreground browser can print and get the token, and then save it locally,

Modify the login component:

<template>
    <div>
        <div v-if="token_username.length <= 0">
            < input placeholder = "user name" type = "text" V-model = "user name" / >
            < input placeholder = "password" type = "text" V-model = "password" / >
            < button @ Click = "loginhandle" > login < / button >
        </div>
        <div v-else>
            {{ token_username }}
        </div>
    </div>
</template>
<script>
export default {
    name: "Login",
    data() {
        return {
            username: "",
            password: "",
            token_username:""
        };
    },
    created(){
        if(localStorage.getItem("token")){
            this.token_username = localStorage.getItem("username");
        }
    },
    methods: {
        loginHandle() {
            //Login process
            this.$api.getLogin({
                    username: this.username,
                    password: this.password
                }).then(res => {
                    if(res.data.code == 400){
                        Alert ("wrong user name and password");
                    }else{
                        this.token_username = res.data.username;
                        localStorage.setItem("token", res.data.token);
                        localStorage.setItem("username",res.data.username)
                    }
                });
        },
        logoutHandle(){
            localStorage.removeItem("token");
            localStorage.removeItem("username");
            this.token_ username = "";  // Let the page refresh
            this.$router.push("/login");
        }
    }
};
</script>
  1. Step 5: the foreground route can read the token value and edit it
router.beforeEach((to,from,next) =>{
  if(to.meta.isLogin){
    //Token: Token
    var token = localStorage.getItem("token");
    if(token){
      next();
    }else{
      next({
        path:"/login"
      })
    }
  }else{
    next();
  }
})

Implementation of login server side authentication part

  1. Step 1: create a new MySQL database, create a table, insert data: Username: Joe and password: 8888.
  2. Step 2: open the background terminal and install the database NPMI — save mysql
  3. Step 3: create one in the mock folder SQLConnect.js The file is used to connect to the database
const mysql = require("mysql");
const MySQLObj = {
    host:"localhost",
    user:"root",
    password:"",
    Database: "web1910" // database name
}

const client = mysql.createConnection(MySQLObj);
function SQLConnect(sql,arr,callback){
    client.query(sql,arr,(error,result)=>{
        if(error){
            console.log(error);
            return;
        }
        callback(result);
    })
}

module.exports = SQLConnect;
  1. Background route introduction and configuration
const SQLConnect = require("./SQLConnect");

const sql = "select * from user where username=? and password=?";
    const arr = [username, password];
    SQLConnect(sql, arr, result => {
        if (result.length > 0) {
            const token = jwt.sign({
                username: username,
                password: password
            }, config.jwtSecret);

            res.send({
                MSG: "login succeeded",
                code: 200,
                token: token,
                username: username
            })
        } else {
            res.send({
                MSG: "login failed",
                code: 400
            })
        }
    })
  1. Login verification was successfully implemented. When clicking on the about page, verify whether the user logs in. If so, enter the about page; If not, jump to the login page. When the user enters the account password on the login page and clicks login, verify whether the entered account password is correct again. If it is correct, enter the login page and you can be allowed to enter the about page; If the account number or password is wrong, a prompt message will be displayed. When you click the log out button, clear the local memorylocalStorageIn addition, the effect of page refresh is realized by changing the stored user name to an empty stringthis.token_username = ” “;adoptthis.$router.push(“/login”)Return to the initialized login page
  2. The complete code of some documents is attached below
//Mock background routing router.js file

const express = require("express");
const router = express.Router();
const config = require("./config");
const jwt = require("jsonwebtoken");
const SQLConnect = require("./SQLConnect");

router.post("/login", (req, res) => {
    const username = req.body.username;
    const password = req.body.password;
    const sql = "select * from user where username=? and password=?";
    const arr = [username, password];
    SQLConnect(sql, arr, result => {
        if (result.length > 0) {
            const token = jwt.sign({
                username: username,
                password: password
            }, config.jwtSecret);

            res.send({
                MSG: "login succeeded",
                code: 200,
                token: token,
                username: username
            })
        } else {
            res.send({
                MSG: "login failed",
                code: 400
            })
        }
    })
})


module.exports = router;
//Front end routing under SRC file router.js file

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Login from "../views/Login"

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path:"/login",
    component:Login
  },
  {
    path: '/about',
    name: 'About',
    meta:{
      isLogin:true
    },
    component: () => import('../views/About.vue')
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

router.beforeEach((to,from,next) =>{
  if(to.meta.isLogin){
    //Token: Token
    var token = localStorage.getItem("token");
    if(token){
      next();
    }else{
      next({
        path:"/login"
      })
    }
  }else{
    next();
  }
})


export default router