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.