vuex登录验证及保持登录状态

不知道vuex的可以先看一下 vuex官方文档,这里就不赘述了。

实现思路:假设我们现在想要访问自己在博客园里写的博客,这时候服务器需要知道当前用户是谁,才能确定我们是否有访问权限并正确地返回我们需要的信息,因此这里必须要进行用户名密码验证,即登录操作,验证成功则跳转到请求页面,不成功则跳转到登录页。关于验证这里有两种情况,一种是输入用户名和密码以后点击登录会触发验证,第二种是没有点击登录,只是单纯的路由跳转,这时候可能存在用户名密码过期从而验证失败的情况,所以我们的验证也要在点击登录以及页面跳转这两种情况下进行。

首先写一个登录框,为登录按钮添加login事件

<el-form ref="loginForm" :model="loginForm" label-width="70px" >
    <el-form-item label="用户名" prop="username">
        <el-input v-model="loginForm.username" placeholder="请输入用户名"></el-input>
    </el-form-item>
    <el-form-item label="密码" prop="password">
        <el-input type="password" v-model="loginForm.password"  @keyup.enter.native="login" placeholder="请输入密码"></el-input>
    </el-form-item>
    <el-form-item>
        <el-button type="primary" class="button" @click="login">登录</el-button>
    </el-form-item>
</el-form>

点击登录按钮后触发store的action里的Login方法,并将用户名和密码作为参数传递过去

login () {
let params
= { 'username': this.loginForm.username, 'password': this.loginForm.password }; this.$store.dispatch('Login', params) .then(() => {this.$router.push({ path: '/' }); }) .catch((error) => { console.log(error.response); }); }

退出登录时触发action里的LogOut方法

logOut () {
  this.$store.dispatch('LogOut').then(() => {
  //跳转到登录页面  
  this.$router.push('/login');
  })
}

创建store.js文件

import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios';

const store = new Vuex.Store({
  state: {
    status: '',
    token: localStorage.getItem('token') || '',
    user: {}
  },
  mutations: {
    auth_request(state) {
      state.status = 'loading';
    },
    auth_success(state, token, user) {
      state.status = 'success';
      state.token = token;
      state.user = user;
    },
    auth_error(state) {
      state.status = 'error';
    },
    logout(state) {
      state.status = ''; 
      state.token = '';
    },
  },
  actions: {
    Login({commit}, user) {
      return new Promise((resolve, reject) => {
      commit('auth_request')
// 向后端发送请求,验证用户名密码是否正确,请求成功接收后端返回的token值,利用commit修改store的state属性,并将token存放在localStorage中 axios.post(
'login', user) .then(resp => { const token = resp.data.token const user = resp.data.user localStorage.setItem('token', token)
// 每次请求接口时,需要在headers添加对应的Token验证 axios.defaults.headers.common[
'Authorization'] = token // 更新token commit('auth_success', token, user) resolve(resp) }) .catch(err => { commit('auth_error') localStorage.removeItem('token') reject(err) }) }) }, LogOut({ commit, state }) { return new Promise((resolve, reject) => { axios.get('Logout') .then(response => { removeIsLogin() localStorage.removeItem('loginUsername');
// 移除之前在axios头部设置的token,现在将无法执行需要token的事务
            delete axios.defaults.headers.common['Authorization'];
     resolve(response)
           })
          .catch(error => {
            reject(error)
          })
      })
    }
  },
  getters: {
// !!将state.token强制转换为布尔值,若state.token存在且不为空(已登录)则返回true,反之返回false
isLoggedIn: state => !!state.token,
authStatus: state => state.status
} }); export default store;

用router.beforeEach控制路由跳转时访问页面的权限 (关于to.matched.some的解释见 https://router.vuejs.org/zh/guide/advanced/meta.html)

router.beforeEach((to, from, next) => {
  // 检测路由配置中是否有requiresAuth这个meta属性
  if (to.matched.some(record => record.meta.requiresAuth)) {
    // 判断是否已登录
    if (store.getters.isLoggedIn) {
      next();      
      return;
    }    
    // 未登录则跳转到登录界面
    next('/login'); 
  } else {
    next() 
  }
})

拦截axios请求处理token过期问题

axios.interceptors.response.use(
  response => {
    return response;
  },
  error => {
    if (error.response) {
      switch (error.response.status) {
        case 401:
        //跳转登录
        this.$store.dispatch(logout);
      }
    }
  }
);
原文地址:https://www.cnblogs.com/zdd2017/p/9871925.html