vue登录拦截

总体流程:
1.在登录页面中的登录方法将账号密码发给后台进行校验,校验成功后将后台返回的token存到浏览器本地(存到哪里,自己根据自己的实际业务来, 我以存到sessionStorage为例)
2.在路由中设置一下前置守卫拦截器,判断跳转路由时sessionStorage存储的token是否为空,为空则调到登录页面
3.设置每次向后台请求时从sessionStorage存储的token带上传给后台,因为后台需要校验

登录页面

<template>
  <div>
    <h1>我是登录页面</h1>
    <p>账号:<input type="text" v-model.trim="username"></p>
    <p>密码:<input type="text" v-model.trim="password"></p>
    <p>
      <button @click="logined">登录</button>
    </p>
  </div>
</template>

<script>
import request from "@/utils/request";  // 这是我自己对axios进行封装的,在文章的最后面会贴出代码
export default {
  name: "login.vue",
  data () {
    return {
      username: "yykk",
      password: "123456"
    }
  },

  methods: {
    logined () {
      let userName = this.username;
      let password = this.password;
      request.post("/login/account/pwd", { userName, password }).then(res => {
        if (res.status == 200) {
          // 把服务器段信息放入到session中  
          sessionStorage.setItem("token", res.data);
          // 这个back是为了用户登录后可以直接跳转到想要去的页面,在路由配置的js文件中有设置
          var back = this.$route.query.back || "/";
          this.$router.push(back);
        }
      }).catch(err => {
        console.error("登录失败!!!", err)
      })
    }
  }

}
</script>

<style scoped>
</style>

路由拦截(router的js文件)

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [{
    path: "/",
    name: "layout",
    component: () => import('@/layout/Layout'),
    redirect: "/index",
    //这里只是重定向浏览器地址,但是渲染还是在父级,
    // 好处:就是可以打破不用和父同名默认是首页的规则
    children: [{
        path: "/index",
        name: "index",
        meta: {
          title: "首页"
        },
        component: () => import('@/views/index')
      },
      {
        path: "/user",
        name: "user",
        meta: {
          title: "用户管理",
          isAuth: true
        },
        component: () => import('@/views/user/index')

      },
      {
        path: "/course",
        name: "course",
        meta: {
          title: "课程管理"
        },
        component: () => import('@/views/course/index')
      },
      {
        path: "/order",
        name: "order",
        meta: {
          title: "订单管理"
        },
        component: () => import('@/views/order/index')
      }

    ]
  },
  {
    path: "/login",
    name: "login",
    component: () => import('@/views/login')
  },
  {
    path: "/toLogin",
    redirect: "/login"
  },
  {
    path: "/error",
    name: "error",
    component: () => import('@/views/error')
  }
]

const router = new VueRouter({
  routes
})

// 前置通知(上面的路由配置可以根据自己的业务需求进行替换,重点在这)
router.beforeEach((to, from, next) => {
  if (to.matched.length == 0) {
    return next({
      path: "/error"
    })
  } else if (to.path == "/login") {
    // 1: 排除不需要拦截的授权的页面
    return next();
  } else {
    //1: 如果登录成功,直接访问成功
    // 在js中判断字符串是否为空的话可以直接这样判断(sessionStorage.token是后台返回的token被存在了sessionStorage中,sessionStorage.token这个可以直接获取)
    if (sessionStorage.token) {
      return next();
    } else {
      // 2: 如果用户访问的受保护的资源,且没有登录,则跳转到登录页面
      // 举个场景:在操作系统,但是突然要吃饭了,过了30分钟以后继续来访问系统。因为token有时间限制。这个肯定会转发登录去、
      // 为了良好的体验
      // 将当前路由的完整的地址做为参数传递给Login.vue的组件,以便登录成功以后继续回到该位置
      return next({
        path: "/login",
        query: {
          back: to.fullPath
        }
      })
    }
  }
  next();
})

// 后置通知
router.afterEach(to => {
  document.title = to.meta.title;
})

export default router

封装axios请求

// 1: 导入异步处理
import axios from "axios";


// 2: 创建axios异步实列对象
const request = axios.create({
  //`baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
  baseURL: "根目录",// 设置后每次都请求都会在前面加上这个url 比如可以写http://127.0.0.1:8081/api/
  // 请求服务器最大时长,如果请求超过这个时间直接终止
  timeout: 10000
  // 设置请求头信息
  //headers: {'X-Custom-Header': 'foobar'}  // 不建议:因为太死了
});

// 添加请求拦截器
// 在执行axios.get/post 在来进行处理加工
request.interceptors.request.use(function (config) {
  // 获取toekn
  var token = sessionStorage.getItem("token");

  if (token) {
    config.headers['Authorization'] = 'Bearer ' + token // 让每个请求携带自定义token 请根据实际情况自行修改
  }

  // get请求映射params参数
  if (config.method === 'get' && config.params) {
    let url = config.url + '?' + tansParams(config.params);
    url = url.slice(0, -1);
    config.params = {};
    config.url = url;
  }

  // 这里处理post逻辑 这个post默认的是application/json 所以后台必须使用@requestBody注解进行接受
  if (config.method === 'post' || config.method === 'put') {
    if (!config.data) {
      config.data = {};
    }
  }

  // 在发送请求之前做些什么
  return config;
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error);
});

// 添加响应拦截器
request.interceptors.response.use(function (response) {
  if (response.data.status === 500) {
    console.log("1")
  } else if (response.data.status === 600) {
    console.log("2")
  } else {
    // 对响应数据做点什么
    return response.data;
  }
}, function (error) {
  // 对响应错误做点什么
  return Promise.reject(error);
});


function tansParams(params) {
  let result = ''
  for (const propName of Object.keys(params)) {
    const value = params[propName];
    var part = encodeURIComponent(propName) + "=";
    if (value !== null && typeof (value) !== "undefined") {
      if (typeof value === 'object') {
        for (const key of Object.keys(value)) {
          if (value[key] !== null && typeof (value[key]) !== 'undefined') {
            let params = propName + '[' + key + ']';
            var subPart = encodeURIComponent(params) + "=";
            result += subPart + encodeURIComponent(value[key]) + "&";
          }
        }

      } else {
        result += part + encodeURIComponent(value) + "&";
      }
    }
  }
  return result
}


// 3: 导出
export default request;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lemon20120331

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值