• vue2+axios配置前端路由守卫并获取登录token


    vue2+axios配置前端路由守卫并获取登录token

    编写登录页面

    编写client/src/views/Login.vue登陆页面:

    <template>
        <div class="login">
            <section class="form_container">
                <div class="manage_tip">
                    <span class="title">马马虎虎资金管理系统</span>
                    <el-form :model="loginUser" :rules="rules" ref="loginForm" label-width="60px" class="loginForm">
                        <el-form-item label="邮箱" prop="email">
                            <el-input v-model="loginUser.email" placeholder="请输入邮箱地址"></el-input>
                        </el-form-item>
                        <el-form-item label="密码" prop="password">
                            <el-input type="password" v-model="loginUser.password" placeholder="请输入密码"></el-input>
                        </el-form-item>
                        <el-form-item>
                            <el-button typeof="primary" class="submit_btn" @click="submitForm('loginForm')">登录</el-button>
                        </el-form-item>
                        <div class="tiparea">
                            <p>还没有账号?现在<router-link to="/register">注册</router-link></p>
                        </div>
                    </el-form>
                </div>
            </section>
        </div>
    </template>
    
    <script>
        export default {
        name: "login",
        components: {},
        data() {
    
            return {
                loginUser: {
                    email: '',
                    password: '' 
                },
                rules: {
                    email: [
                        {
                            type: "email",
                            required: true,
                            message: "邮箱格式不正确",
                            trigger: "blur"
                        }
                    ],
                    password: [
                        {
                            required: true,
                            message: "密码不能为空",
                            trigger: "blur"
                        },
                        {
                            min: 6,
                            max: 30,
                            message: "密码长度在6至30个字符之间",
                            trigger: "blur"
                        }
                    ]
                }
            }
         },
         methods: {
             submitForm(formName) {
                 this.$refs[formName].validate(valid => {
                     if (valid) {
                         this.$axios.post("/api/users/login", this.loginUser)
                             .then(res => {
                                 //拿到token
                                 console.log(res);
                             });
                         //跳转页面
                         this.$router.push('/index');
                     } else {
                         console.log('error submit!!');
                         return false;
                     }
                 });
             }
         }
     }
    </script>
    
    <style scoped>
        .login {
            position: relative;
            width: 100%;
            height: 100%;
            background: url(../assets/bg.jpg) no-repeat center center;
            background-size: 100% 100%;
        }
    
        .form_container {
            width: 370px;
            height: 210px;
            position: absolute;
            top: 20%;
            left: 34%;
            padding: 25px;
            border-radius: 5px;
            text-align: center;
        }
    
        .form_container .manage_tip .title {
            font-family: "Microsoft YaHei";
            font-weight: bold;
            font-size: 26px;
            color: #fff;
        }
    
        .loginForm {
            margin-top: 20px;
            background-color: #fff;
            padding: 20px 40px 20px 20px;
            border-radius: 5px;
            box-shadow: 0px 5px 10px #cccc;
        }
    
        .submit_btn {
            width: 100%;
        }
    
        .tiparea {
            text-align: right;
            font-size: 12px;
            color: #333;
        }
    
        .tiparea p a {
            color: #409eff;
        }
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130

    编辑client/src/router/index.js,配置登录页面路由:

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import Index from '../views/Index.vue'
    import Register from '../views/Register.vue'
    import Login from '../views/Login.vue'
    import NotFound from '../views/404.vue'
    
    Vue.use(VueRouter)
    
    const routes = [
      {
        path: '/',
        redirect: 'index'
      },
      {
        path: '/index',
        name: 'index',
        component: Index
        },
      {
          path: '/register',
          name: 'register',
          component: Register
        },
      {
            path: '/login',
            name: 'login',
            component: Login
        },
      {
          path: '*',
          name: '/404',
          component: NotFound
      }
    ]
    
    const router = new VueRouter({
      mode: 'history',
      base: process.env.BASE_URL,
      routes
    })
    
    export default router
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    获取登录token

    编辑Login.vue中的submitForm,登陆成功后获取token并存储到localStorage

    methods: {
             submitForm(formName) {
                 this.$refs[formName].validate(valid => {
                     if (valid) {
                         this.$axios.post("/api/users/login", this.loginUser)
                             .then(res => {
                                 //拿到token
                                 //console.log(res);
                                 const { token } = res.data;
                                 // 存储token到LocalStorage
                                 localStorage.setItem('eleToken', token);
                                 //跳转index页面
                                 this.$router.push('/index');
                             });
            
                     } else {
                         console.log('error submit!!');
                         return false;
                     }
                 });
             }
         }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    配置路由守卫

    在未登录状态下,只能访问注册页面或者登陆页面,无法访问Index等其他页面。

    编辑client/src/router/index.js
    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import Index from '../views/Index.vue'
    import Register from '../views/Register.vue'
    import Login from '../views/Login.vue'
    import NotFound from '../views/404.vue'
    
    Vue.use(VueRouter)
    
    const routes = [
      {
        path: '/',
        redirect: 'index'
      },
      {
        path: '/index',
        name: 'index',
        component: Index
        },
      {
          path: '/register',
          name: 'register',
          component: Register
        },
      {
            path: '/login',
            name: 'login',
            component: Login
        },
      {
          path: '*',
          name: '/404',
          component: NotFound
      }
    ]
    
    const router = new VueRouter({
      mode: 'history',
      base: process.env.BASE_URL,
      routes
    })
    
    //路由守卫
    router.beforeEach((to, from, next) => {
        const isLogin = localStorage.eleToken ? true : false;
        if (to.path == '/login' || to.path == '/register') {
            next();
        } else {
            isLogin ? next() : next('/login');
        }
    });
    
    export default router
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    配置请求/响应拦截

    编辑http.js,在axios请求拦截中配置统一请求头,在响应拦截中配置token过期时的处理动作。

    import axios from 'axios';
    import { Message, Loading } from 'element-ui';
    import router from './router';
    
    // 定义加载动画方法
    let loading;
    function startLoading() {
        loading = Loading.service({
            lock: true,
            text: "稍待片刻...",
            background: 'rgba(0,0,0,0,7)'
        });
    }
    
    function endLoading() {
        loading.close();
    }
    
    // 请求拦截
    axios.interceptors.request.use(config => {
        startLoading();
    
        if (localStorage.eleToken) {
            // 设置统一的request header
            config.headers.Authorization = localStorage.eleToken;
        }
    
        return config;
    }, error => {
        return Promise.reject(error);
    })
    
    // 响应拦截
    axios.interceptors.response.use(response => {
        endLoading();
        return response;
    }, error => {
        endLoading();
        Message.error(error.response.data);
    
        //获取错误状态码,并清除过期的token
        const { status } = error.response;
        if (status == 401) {
            Message.error('Token已过期,请重新登录!');
            // 清除失效token
            localStorage.removeItem('eleToken');
            // 跳转到登录页面
            router.push("/login");
        }
    
        return Promise.reject(error);
    })
    
    export default axios;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
  • 相关阅读:
    Charles通过Rewrite越过OPTIONS请求拦截
    Java开发面试--Redis专区
    Spring系列文章3:基于注解方式依赖注入
    C++基于Qt中QOpenGLWidget模块实现的画图板源码+可执行文件
    【Java】JDBC基础使用教程
    解读JVM级别本地缓存Caffeine青出于蓝的要诀 —— 缘何会更强、如何去上手
    “人间自有真情在,宜将寸心报春晖”四川翼嘉酒业董事长杨涛 为清华学子送上“爱心大礼”
    19 螺旋矩阵
    分享一套好用的功能测试用例编写框架
    Ansible原理和安装
  • 原文地址:https://blog.csdn.net/Sebastien23/article/details/125493047