1. Preparations for the server

To verify the user, the backend needs to record the user’s status when the user logs in, encrypt it, and then return it to the front-end. All subsequent requests of the user should be accompanied by the encrypted state. The backend decrypts this state and compares it with the previously saved state to determine whether the user is logged in or legitimate.

Here I use Node to write a simple local Express service to achieve this function. The full code is posted directly:

// server.js
const express = require('express');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');

const app = express();
// secret is the key for back-end encryption
const secret = 'rhwl';

app.use((req, res, next) = > {
  res.header('Access-Control-Allow-Origin'.The '*');
  res.header('Access-Control-Allow-Methods'.'GET,HEAD,OPTIONS,POST,PUT');
  res.header('Access-Control-Allow-Headers'.'Origin, X-Requested-With, Content-Type, Accept, Authorization');
  if (req.method.toLowerCase() === 'options') {
    return res.end();
  }
  next();
});
app.use(bodyParser.json());
app.post('/login', (req, res) => {
  const { username } = req.body;
  if (username === 'admin') { // If the user is a legitimate user, use JWT to encrypt the token
    res.json({
      code: 0.username: 'admin'.token: jwt.sign({ username: 'admin' }, secret, {
        expiresIn: 20,})}); }else {
    res.json({
      code: 1.data: 'Username does not exist'}); }}); app.get('/validate', (req, res) => {
  const token = req.headers.authorization; // Include token information in the request header
  jwt.verify(token, secret, (err, decode) => { // Verify that the token is valid
    if (err) {
      return res.json({
        code: 1.data: 'Current token is invalid'}); }// If the validation is valid, a new token is generated and the information is returned
    res.json({
      username: decode.username,
      code: 0.token: jwt.sign({ username: 'admin' }, secret, {
        expiresIn: 20,})}); }); }); app.listen(3000, () = > {console.log('Server running on port 3000');
});
Copy the code

2. Axios encapsulation in the project

We then wrapped ajax requests in projects that fit our needs, which are now usually based on axiOS libraries. In your own wrapped Ajax plug-in, you add a token to the request header each time. Code implementation:

// ajaxResquest.js
import axios from 'axios';

class ajaxResquest {
    constructor() {// Automatically switch baseURL based on the current mode
        this.baseURL = process.env.NODE_ENV === 'development' ? 'http://localhost:3000' : '/';
        this.timeout = 5000; // Set the request timeout to 5s
    }
    request(config){
        const instance = axios.create({
            baseURL: this.baseURL,
            timeout: this.timeout,
        });
        
        instance.interceptor.request.use((config) = > {
            // Add the locally stored token to the request header of each request
            // This can be implemented along with the request to attach the user's verification information requirements
            config.headers.Authorization = localStorage.getItem('token');
            return config;
        }, (err) => {
            return Promise.reject(err);
        });
        instance.interceptor.response.use((req,res) = > {
            return req.data;
        }, (err) => {
            Promise.reject(err);
        });
        
        // Add the parameters required when using request to instance
        returninstance(config); }}export default new ajaxRequest();
Copy the code

Then unified management of the project API interface:

// api.js
import ajax from 'ajaxResquest';
export const userLogin = (username) = > ajax.request({url: '/login'.method: 'POST'.data: {
    username,
}});
export const userValidate = (a)= > ajax.request({url: '/validate'});
Copy the code

Next, we implement the requirements of user login and authority verification in the project.

3. Vuex records user login

First, the login component is used with VUEX to trigger user login, and the information after user login is saved in VUEX. The code of the login component is as follows:

// userLogin component
<template>
    <div>
        <el-input style="width:200px" v-model="username"></el-input>
        <el-button @click="login"</el-button> </div> </template> <script>export default {
    data() {return {
            username: ' ',
        }
    },
    methods: {
        login(){// This triggers actions in vuex to invoke the user login interface // to save the user login state to this in vuex.$store.dispatch('login', this.username).then((data) => {// After login, route to the user account page or do what you need to do this.$router.push('/profile');
            });
        }
    }
}
</script>
Copy the code

Next comes vuex’s store.js

// store.js
import Vue from 'vue';
import Vuex from 'vuex';
import {userLogin, userValidate} from 'api.js';

Vue.use(Vuex);

export default Vuex.store({
    state: {
        username: ' ',},mutations: { setUsername(state, username){ state.username = username; }},actions: {
        async login({commit}, username){
            const res = await userLogin(username);
            if (res.code === 1) { // Login failed
                return Promise.reject(res);
            }
            // After successful login, save the token returned by the interface locally
            localStorage.setItem('token', res.token);
            // Save the user name in vuex
            commit('setUsername', username); }}});Copy the code

After the preceding operations, the operation of invoking the login interface during user login is realized through VUex. The user name after successful login is saved in VUex, and the token is saved locally in the browser. However, the data in vuex is not persistent data, and the saved username will disappear after refreshing. Next, we will implement user verification when refreshing the page or route jump. If the verification passes, new token and username will be generated and saved.

4. Vuex works with vuE-Router to verify login

When a user refreshes the page or clicks another page to switch to a router, the validate interface of the backend is invoked. The interface verifies the saved token to verify the validity of the current user. We added the following code to vuex’s store.js:

export default Vuex.store({
    state: {
        username: ' ',},mutations: { setUsername(state, username){ state.username = username; }},actions: {
        async login({commit}, username){
            ...
        },
        async validate({commit}) {
            // When userValidate is called, the
            const res = await userValidate();
            if (res.code === 1) { // User verification fails
                return Promise.reject(res);
            }
            // If the verification succeeds, save the token and username again
            localStorage.setItem('token', res.token);
            commit('setUsername', res.username); }}});Copy the code

Basically we have achieved all the prerequisites for user permission control with the above code:

  • The user logs in successfully and saves the token locally
  • Add the saved token information to the request header of your own wrapped Ajax
  • The back-end service verifies front-end tokens

Then the next step is how to control the permission when the router is refreshed or changed.

5. Vue-router hook realizes user permission control

Vue-router, for those of you who have used vue-Router, also has hook functions, which are called navigational guards in the official documentation. The navigational guard allows us to operate precisely as each route changes, and we determine user permissions here. In the main.js of the vue project:

import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

// Use the navigation guard of the route here for permission control
// You can customize a route whitelist that does not require authentication
const whiteList = ['/'];
router.beforeEach(async  (to, from, next) => {
    // The page to go to is whitelisted
    if (whiteList.includes(to.path)) {
        next();
    }
    // Instead of a whitelist, call the validate behavior in vuex
    const flag = await store.dispatch('validate');
    if (flag) { // The user passes the verification
        next();
    } else { // User verification failed
        next('/login'); // Jump to the user login page
        // By the way, you can also add isNeeded: true/false to the meta attribute in the router
        // Then use this property to more finely control whether the page is allowed to jump if the user fails the verification}});// vuex
Vue.use(ElementUI);
Vue.config.productionTip = false;

new Vue({
    router,
    store,
    render: h= > h(App),
}).$mount('#app');
Copy the code

Ok, the above is vuEX, which is organized by me, combined with router to achieve user permission control. I hope it will be helpful to you. (The content of this share comes from a vUE advanced course, sorted and shared by myself ~)


About the author: Gong Chenguang,And in the futureBig data front-end engineer.