深刻Vue後臺管理開發之登陸驗證

1.登陸方法

1.1 傳統身份驗證的方法

  1. 用戶提交登陸信息
  2. 服務端生成一條記錄,其中會說明用戶信息
  3. 服務端返回記錄的ID號給客戶端
  4. 這個ID號會被存儲在客戶端的Cookie裏,下次用戶再向服務端發送請求時能夠帶着這個Cookie,這樣服務端會驗證該Cookie裏的信息,若是找到對應的記錄,說明用戶經過了身份驗證,就把用戶請求的數據返回給客戶端
  5. 而上面再服務端生成的就是用戶的Session,須要再服務端按期清理過時的Session

1.2 基於 token 的登陸流程

  1. 客戶端使用用戶名跟密碼請求登陸
  2. 服務端收到請求,去驗證用戶名與密碼
  3. 驗證成功後,服務端會簽發一個Token,再把這個Token發送給客戶端
  4. 客戶端收到Token之後能夠把它存儲起來,好比放在Cookie裏或者Local Storage
  5. 客戶端每次向服務端請求資源的時候須要帶着服務端簽發的Token
  6. 服務端收到請求,而後去驗證客戶端請求裏面帶着的Token,若是驗證成功,就向客戶端返回請求的數據

1.3 token 做用

  • token存入本地cookie中,能夠保證每次刷新時用戶登陸狀態不丟失
  • 經過token,還能夠獲取到用戶的其餘信息

2. 邏輯代碼

2.1. 登陸事件

點擊`handleLogin`觸發`vuex`中`actions`的`Login`派發行爲
複製代碼
handleLogin() {
      this.$store
          .dispatch('Login', this.loginForm)
          .then(() => {
            this.$router.push({ path: '/' });
          })
          .catch(() => {
            
          })
    }
複製代碼

2.2. store.js

而後回到vuex,這裏的store.js改爲store文件夾,分模塊管理vuexjavascript

// 文件夾結構
|-- store
  |-- modules
  |-- getters.js
  |-- index.js
複製代碼

咱們劃分出,app, user 兩個模塊,在 user 裏控制用戶的登陸信息,app 中存儲應用的狀態,如全局loading或者控制第三方組件的全局大小,如element-ui中的全局組件size前端

// index.vue
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import getters from './getters'

Vue.use(Vuex)
const store = new Vuex.Store({
  modules: {
    user
  },
  getters
})

export default store
複製代碼

user.js中存儲了登陸事件所需的事件和數據,handleLogin事件觸發的是modulesuser模塊的actions,這裏user.js中的具體方法和state數據,均是封裝過的vue

2.3 request 請求封裝

  1. utils/auth.js中封裝設置cookie的方法
// 導入 Cookies
import Cookies from 'js-cookie'

// 設置 cookie name
const TokenKey = 'Admin-Token'

// 獲取 Admin-Token 的 cookie
export function getToken() {
  return Cookies.get(TokenKey);
}

// setToken 
export function setToken(token) {
  return Cookies.set(TokenKey, token);
}

// 移除 token
export function removeToken() {
  return Cookies.remove(TokenKey)
}
複製代碼
  1. utils/request中封裝axios請求設置
import axios from 'axios'
import store from '../store'
import { getToken } from '@/utils/auth'

const service = axios.create({
  baseURL: 'http://193.112.153.155:3001',
  timeout: 5000  // 請求超時時間
})
export default service
複製代碼
  1. 在api/login.js中封裝登陸api請求
import request from '@/utils/request'

export function login(username, password) {
  return request({
    url: '/user/login',
    method: 'post',
    data: {
      username,
      password
    }
  })
}

export function getInfo(token) {
  return request({
    url: '/user/info',
    method: 'get',
    params: { token }
  })
}

export function logout() {
  return request({
    url: '/user/logout',
    method: 'post'
  })
}
複製代碼
  1. 再回到modules/user.js中完成登陸的store
import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'

const user = {
  state: {
    token: getToken(),
    name: '',
    avatar: '',
    roles: []
  },

  mutations: {
    SET_TOKEN: (state, token) => {
      state.token = token
    },
    SET_NAME: (state, name) => {
      state.name = name
    },
    SET_AVATAR: (state, avatar) => {
      state.avatar = avatar
    },
    SET_ROLES: (state, roles) => {
      state.roles = roles
    }
  },

  actions: {
    // 登陸
    Login({ commit }, userInfo) {
      const username = userInfo.username.trim()
      return new Promise((resolve, reject) => {
        login(username, userInfo.password).then(response => {
          const data = response.data;
          setToken(data.token)
          commit('SET_TOKEN', data.token);
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },

    // 獲取用戶信息
    GetInfo({ commit, state }) {
      return new Promise((resolve, reject) => {
        getInfo(state.token).then(response => {
          const data = response.data
          if (data.roles && data.roles.length > 0) { // 驗證返回的roles是不是一個非空數組
            commit('SET_ROLES', data.roles)
          } else {
            reject('getInfo: roles must be a non-null array !')
          }
          commit('SET_NAME', data.name)
          commit('SET_AVATAR', data.avatar)
          resolve(response)
        }).catch(error => {
          reject(error)
        })
      })
    },

    // 登出
    LogOut({ commit, state }) {
      return new Promise((resolve, reject) => {
        logout(state.token).then(() => {
          commit('SET_TOKEN', '')
          commit('SET_ROLES', [])
          removeToken()
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },

    // 前端 登出
    FedLogOut({ commit }) {
      return new Promise(resolve => {
        commit('SET_TOKEN', '')
        removeToken()
        resolve()
      })
    }
  }
}

export default user
複製代碼

本文僅供我的學習總結使用 參考:java

vue+axios 實現登陸攔截權限驗證ios

手摸手,帶你用vue擼後臺 系列二(登陸權限篇) )vuex

相關文章
相關標籤/搜索