Vue project login module

Login Module

Needs to be done to guard the route, some modules are to be protected, you must be logged in to visit. Common practice is to add routes meta:{ auth:true }to do the identification, it expressed the need to do certification.

// 路由守卫
router.beforeEach((to, from, next) => {
    // 判断要进入的路由是否需要认证
    if(to.meta.auth) {
        // 通过token令牌机制判断是否已经登录
        const token = localStorage.getItem('token');
        if (token) {
            next(); // 如果登录则放行,进入路由
        } else {
            // 跳转,并携带重定向地址
            next({
               path: '/login', 
               query: {
                   redirect: to.path 
               }
            });
        }
    } else {
        // 不需要验证的模块,直接放行
        next();
    }
});

In Vuex stored login status isLogin

import Vue from 'vue'
import Vuex from 'vuex'
import user from './service/user'

Vue.use(Vuex);
export default new Vuex.Store({
    state: {
        isLogin: localStorage.getItem('token') ? true : false
    },
    mutations: {
        setLoginState(state, bool) {
            state.isLogin = bool;
            // true 表示登录,false 表示注销
        }
    },
    actions: {
        login({commit}, user) {
            // 发起登录请求,请求都拆分出去 service 文件夹中
            // 使用 service 的请求方法
            user.login(user).then(res => {
                // 从 res.data 中解构数据,code和token
                const { code, token } = res.data;
                if (code) {
                    // 登录成功,修改Vuex中间的登录状态
                    commit('setLoginState', true);
                    // 缓存令牌 token
                    localStorage.setItem("token", token);
                }
                return code; // 返回code 给下一个 .then 使用
            });
        },
        logout({ commit }) {
            // 清除缓存
            localStorage.removeItem('token');
            // 重置状态
            commit('setLoginState', false);
        }
    }
});

serviceFolder service

// 返回一个 Promises 方便外面使用
import axios from 'axios'
export default {
    login(user) {
        // 注意:请求地址最好是抽出去统一管理
        return axios.get('/api/login', { 
            params: user 
        });
    }
}

Log submit event processing components

// 提交函数中, dispatch 是调用 actios 中的方法,在通过 commit 发送 mutations 方法修改数据
// 注意:this.model 就是传递的数据
this.$store.dispatch("login", this.model)
    .then(code => {
        if (code) {
            // 登录成功后,重定向,如果没有则重定向到首页
            const path = this.$route.query.redirect || '/';
            this.$router.push(path);
        }
    }).catch(error => {
        // 有错误发生 或 登录失败
        const toast = this.$createToast({
            time: 2000,
            text: error.message || error.response.data.message || "登录失败",
            type: "error"
        });
        toast.show();
    });

Checkpoints need to be considered

  • How to guard the route
  • How asynchronous operation
  • Saving registration status
  • How analog interface

HTTP Interceptor

New interceptor.jsfile, requests and responses for intercepting

// token 过期导致请求失败的情况可能出现在项目的任何地方,可以通过响应拦截统一处理
// 拦截器的作用:是对接口做一层保护,表示所有的接口都会带有令牌 token  
// 可以查看 axios 的文档 : http://www.axios-js.com/zh-cn/docs/
const axios = require('axios');

export default function(vm) {
    // HTTP 请求拦截器
    axios.interceptors.request.use(config => {
        // 在发送请求之前做些什么
        // 获取token, 并添加到 headers 请求头中
        const token = localStorage.getItem('token');
        if (token) {
            config.headers.token = token;
        }
        return config;
    });
    
    // HTTP 响应拦截器
    // 统一处理 401 状态,token 过期的处理,清除token跳转login 
    // 参数 1, 表示成功响应
    axios.interceptors.response.use(null, err => {
        // 没有登录或令牌过期
        if (err.response.status === 401) {
            // 注销,情况状态和token
            vm.$store.dispatch("logout");
            // 跳转的登录页
            vm.$storer.push('/login');
            // 注意: 这里的 vm 实例需要外部传入
        }
        return Promise.reject(err);
    });
}

// 使用拦截器
// 1. 引入拦截器文件
import interceptor from './interceptor'
// 执行拦截器初始化
interceptor(vm);

Logout

  • In both cases token need to clear the cache:
    1. Users initiative to cancel
    2. token expired
  • It needs to be done:
    • Empty the cache
    • Reset login status
    methods: {
      logout() {
          this.$route.dispatch('login');
      }
    }

Token-depth understanding of the mechanism

  • Bearer Token Specification
    • Concept: Describes how to use tokens in the HTTP specification OAuth2 access to protected resources
    • Features: Token is the ID card, no need to prove ownership of the token
    • Specifications: Auuthorization defined in the request header: Bearer token
  • Json Web Token specification https://jwt.io
    • Concept: the way tokens specific definition
    • States: the first token configuration, payload, signed by three parts
    • Head: contains the encryption algorithm, the token type and other information
    • Load: containing user information, the issue of time, and expiration time information
    • Signature: the hash string obtained according to the header, payload and a secret key encryption

Drops Cube-UI library sophisticated mobile end component library

Cube-UI library address

Guess you like

Origin www.cnblogs.com/yuxi2018/p/11967311.html
Recommended