整体思路:
- 登录时,判断登录状态(从session中拿登录信息),(若没有登录信息)发送登录请求,成功后将后台返回的登录用户信息(token)存在sessionStorage中。
- 接口请求时,在axios请求拦截器中给http头携带token发送给后台,用于验证登录状态是否过期(request interceptors)。
- 请求时token如果过期,清除sessionstorage的用户信息,并重定向到登录页。
- 路由跳转时,利用vue-router提供的钩子函数beforeEach()对路由进行判断,非登录页且存在token就next(),不存在token便跳转到登录页面。
vuex
先把要管理的登录状态写完整(store->index.js)
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
|
import Vue from "vue"; import Vuex from "vuex";
Vue.use(Vuex); export default new Vuex.Store({ state: { token: null, //登录信息(也可以是登录用户信息,由后台定) isLogin: false, //登录状态 }, getters:{ //获取登录状态 isLogin(state){ return state.isLogin } }, mutations: { Login(state, data){ sessionStorage.setItem('token',data); state.isLogin = true; state.token = data; }, Logout(state){ sessionStorage.removeItem('token'); state.isLogin = false; state.token = null; } } })
|
登录
Login.vue
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
|
methods:{ isLogin(){ if(session.getItem('token')){ this.$store.commit('Login', session.getItem('token')); }else{ this.$store.commit('Logout'); } return this.$store.getters.isLogin; }, login(){ this.$http.post('/api/login').then(res => { this.$store.commit('Login', res.token); let redirect = decodeURIComponent(this.$route.query.redirect || '/index'); this.$router.push({ path: redirect }) }).catch(err=>{ this.$store.commit('Logout'); }) } }) }
|
http拦截
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
|
axios.interceptors.request.use(config => { if(store.state.token){ config.headers.Authorization = <span class="subst">${store.state.token}</span> } return config })
axios.interceptors.response.use( response => { return response; }, err => { if(err.response){ switch (error.response.status) { case 401: router.replace({ path: '/login', query: { redirect: router.currentRoute.fullPath } }); break; case 403: store.commit('Logout'); router.replace({ path: '/login', query: { redirect: router.currentRoute.fullPath } }); } return Promise.reject(error.response.data) } })
|
路由拦截
router>index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
router.beforeEach((to, from, next) => { if (to.path !== '/login' && !store.state.token) { next({ path: '/login', query: { redirect: to.fullPath } }) } next() })
|
近期评论