zoukankan      html  css  js  c++  java
  • Vue 项目 login 模块

    登录模块

    需要做路由的守卫,有些模块是需要被保护的,必须登录才能访问。 常见手法是给路由添加 meta:{ auth:true } 来做标识,表示需要做认证。

    // 路由守卫
    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();
        }
    });
    

    在 Vuex 中存储登录状态 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);
            }
        }
    });
    

    service文件夹下的服务

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

    登录组件中提交事件处理过程

    // 提交函数中, 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();
    	});
    

    需要考虑的检查点

    • 如何守卫路由
    • 如何进行异步操作
    • 如何保存登录状态
    • 如何模拟接口

    HTTP 拦截器

    新建 interceptor.js 文件,用于拦截请求和响应

    // 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);
    

    注销

    • 需要清除 token 缓存的两种情况:
      1. 用户主动注销
      2. token 过期
    • 需要做的事情:
      • 清空缓存
      • 重置登录状态
    methods: {
        logout() {
            this.$route.dispatch('login');
        }
    }
    

    深入理解令牌机制

    • Bearer Token规范

      • 概念: 描述在HTTP访问OAuth2保护资源时如何使用令牌的规范
      • 特点:令牌就是身份证,无需证明令牌的所有权
      • 具体规定:在请求头中定义Auuthorization:Bearer token
    • Json Web Token 规范 https://jwt.io

      • 概念:令牌的具体定义方式
      • 规定:令牌由三部分构成 头、载荷、签名
      • 头:包含加密算法、令牌类型等信息
      • 载荷:包含用户信息、签发时间和过期时间等信息
      • 签名:根据头、载荷及秘钥加密得到的哈希串

    滴滴 Cube-UI 库 精致的移动端组件库

    Cube-UI 库地址

  • 相关阅读:
    Filter的基本配置
    11.3、4(filter的生命周期和API)、
    11.1(过滤器概述)、(创建过滤器filter)
    10.6商品的促销活动,(未解决)
    php 调用常量或者变量的时候千万不能加引号""'' 不然不生效
    thinkphp5 if else的表达式怎么写?
    request() 获取参数是数组不是对象
    thinkphp5 PATHINFO路由正确的访问方式
    thinkphp5 的iframe文件怎么显示到html里面
    thinkphp5引入外部css js文件
  • 原文地址:https://www.cnblogs.com/yuxi2018/p/11967311.html
Copyright © 2011-2022 走看看