在vue js中刷新页面时保持用户会话登录

时间:2019-07-30 21:00:56

标签: django vue.js jwt axios vuex

我正在vue js中创建用户登录页面,并使用axios从django消费数据。我已经利用jwt在客户端创建令牌会话

问题是刷新页面时未保存会话。我为此感到沮丧。这是我的源代码:

在'../ src / store / modules / auth.js'

import Vue from 'vue'
import Axios from 'axios'
import 'es6-promise/auto'

// In order that Axios work nice with Django CSRF
Axios.defaults.xsrfCookieName = 'csrftoken'
Axios.defaults.xsrfHeaderName = 'X-CSRFToken'

const state = {
  authUser: {},
  users: [],
  isAuthenticated: false,
  jwt: localStorage.getItem('token'),
  endpoints: {
    obtainJWT: 'http://127.0.0.1:8000/api/auth/obtain_token/',
    refreshJWT: 'http://127.0.0.1:8000/api/auth/refresh_token/',
    baseUrl: 'http://127.0.0.1:8000/api/auth/',
    register: 'http://127.0.0.1:8000/signup/'
  }
}

const mutations = {
  setAuthUser: (state, {
    authUser,
    isAuthenticated
  }) => {
    Vue.set(state, 'authUser', authUser)
    Vue.set(state, 'isAuthenticated', isAuthenticated)
  },

  updateToken: (state, newToken) => {
    localStorage.setItem('token', newToken);
    state.jwt = newToken;
  },

  removeToken: (state) => {
    localStorage.removeItem('token');
    state.jwt = null;
  },
}

const actions = {
  refreshToken(){
    const payload = {
      token: this.state.jwt
    }      
    Axios.post(state.endpoints.refreshJWT, payload)
      .then((response)=>{
          this.commit('updateToken', response.data.token)
        })
      .catch((error)=>{
          console.log(error)
        })
  }
}

export default {
  state,
  mutations,
  actions,
}

在'../ src / store / index.js'

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
import auth from './modules/auth'

Vue.use(Vuex)

// Make Axios play nice with Django CSRF
axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = 'X-CSRFToken'

export default new Vuex.Store({
  modules: {
    auth
  },
})

在'../ src / components / login.vue'

<template>
  <div class="login">
    <form>
      <label for="username">Username</label>
      <input 
        type="text" 
        name="username" 
        v-model="username" 
      /><br>
      <label for="password">Password</label>
      <input 
        type="password" 
        name="password" 
        v-model="password"  
      /><br>
      <input 
        type="button"  
        @click="login()" 
        value="Login" 
      />
    </form>
</template>

<script>
import axios from 'axios'
/* eslint-disable */ 
export default {
  name: 'Login',
  data(){
    return {
      username: '',
      password: ''
    }
  },
  methods: {
    login(){
      const payload = {
        username: this.username,
        password: this.password
      }
      axios.post(this.$store.state.auth.endpoints.obtainJWT, payload)
        .then((response) => {
          this.$store.commit('updateToken', response.data.token)
          this.$store.commit('setAuthUser',
            { 
              authUser: response.data, 
              isAuthenticated: true
            }
          )
          this.$router.push({path: 'dashboard-user/id/list-vendor'})
        })
        .catch((error) => {
          //NOTE: erase this when production
          console.log(error);
          console.debug(error);
          console.dir(error);
          alert("The username or password is incorrect");
        })
    }
  }
}
</script>

在“ main.js”中

import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'
import 'tachyons'
import routes from './routes'
import './styles.css'
import store from '@/store'

Vue.config.productionTip = false
Vue.use(VueRouter)

import '@/assets/fonts/all.css';

const router = new VueRouter({
  mode: 'history',
  routes
})

router.beforeEach((to, from, next) => {
  // to and from are both route objects. must call `next`.
  if(to.fullPath === '/dashboard-user/id/list-vendor') {
    if(!store.state.jwt) {
      next('/login')
    }
  }
  if(to.fullPath === '/login') {
    if(store.state.jwt) {
      next('/dashboard-user/id/list-vendor')
    }
  }
  next();
})

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

1 个答案:

答案 0 :(得分:0)

由于使用寄存器auth作为模块,因此应使用store.state.auth.jwt而不是store.state.jwt

router.beforeEach((to, from, next) => {
  // to and from are both route objects. must call `next`.
  if(to.fullPath === '/dashboard-user/id/list-vendor') {
    if(!store.state.auth.jwt) {
      next('/login')
    }
  }
  if(to.fullPath === '/login') {
    if(store.state.auth.jwt) {
      next('/dashboard-user/id/list-vendor')
    }
  }
  next();
})