深入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文件夹,分模块管理vuex

// 文件夹结构
|-- 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数据,均是封装过的

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
复制代码

本文仅供个人学习总结使用 参考:

vue+axios 实现登录拦截权限验证

手摸手,带你用vue撸后台 系列二(登录权限篇) )

转载于:https://juejin.im/post/5ccff43251882541ca034951

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值