关键词

vue2模拟vue-element-admin手写角色权限的实现

Vue2模拟Vue-element-admin手写角色权限的实现,可以通过以下步骤完成:

1. 安装依赖

首先需要安装以下依赖:Vue-Router(用于控制路由)、Axios(用于发送http请求),可使用如下命令:

npm install vue-router axios

2. 构建基本页面布局

在Vue项目中创建相应的组件并进行基本页面布局,如Header、Sidebar、Main和Footer等组件,实现页面骨架。其中Sidebar组件应该是动态的,具体需要渲染什么样的内容应该根据用户登录后的角色来进行动态判断。

3. 实现登录功能

登录页面可以使用表单组件做到简单易用,实现用户输入账号、密码的过程,并通过Axios向后端发送http请求进行验证。服务器返回成功则将用户信息和Token等基本信息保存到本地存储中(localStorage),并跳转到主页面。如果验证失败则需要提示用户输入错误信息。

4. 实现角色控制

主页面应该实现菜单、路由、页面权限的控制,其中菜单应该是动态生成的,具体内容取决于用户的角色。用户登录成功后,从本地存储中获取用户信息,把用户拥有的菜单和路由等权限信息渲染到页面上。如果用户没有相应的权限,应该隐藏或禁用对应的菜单和路由。

5. 后端接口实现

当我们控制好了前端的权限时,还需要在后端进行相应的控制,防止恶意输入、越权操作等。

两个示例说明:

示例一:实现角色控制

  1. 安装Vue-Router和Axios
npm install vue-router axios
  1. 创建路由配置文件router.js
import Vue from 'vue'
import Router from 'vue-router'
import store from './store'

Vue.use(Router)

// 根据用户角色控制路由
const router = new Router({
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/about',
      name: 'about',
      component: About,
      meta: {
        requiresAuth: true,
        roles: ['admin']
      }
    },
    {
      path: '/login',
      name: 'login',
      component: Login
    }
  ]
})

// 全局路由拦截器
router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth) {
    // 用户未登录,跳转到登录页面
    if (!store.getters.isLoggedIn) {
      next('/login')
    } else {
      // 用户没有权限,跳转到主页面
      if (to.meta.roles.indexOf(store.getters.getUserRole) === -1) {
        next('/')
      } else {
        next()
      }
    }
  } else {
    next()
  }
})

export default router
  1. 创建Store文件夹,并添加user.js文件
import axios from 'axios'

const state = {
  token: localStorage.getItem('token') || '',
  user: {},
  role: ''
}

const getters = {
  isLoggedIn: state => !!state.token,
  getUser: state => state.user,
  getUserRole: state => state.role
}

const actions = {
  login ({ commit }, user) {
    return new Promise((resolve, reject) => {
      axios.post('/api/login', user)
        .then(res => {
          const token = res.data.token
          const user = res.data.user
          localStorage.setItem('token', token)
          axios.defaults.headers.common['Authorization'] = token
          commit('auth_success', { token, user })
          resolve(res)
        })
        .catch(err => {
          commit('auth_error')
          localStorage.removeItem('token')
          reject(err)
        })
    })
  },
  logout ({ commit }) {
    return new Promise((resolve, reject) => {
      commit('logout')
      localStorage.removeItem('token')
      delete axios.defaults.headers.common['Authorization']
      resolve()
    })
  }
}

const mutations = {
  auth_success (state, payload) {
    state.token = payload.token
    state.user = payload.user
    state.role = payload.user.role
  },
  auth_error (state) {
    state.token = ''
    state.user = {}
    state.role = ''
  },
  logout (state) {
    state.token = ''
    state.user = {}
    state.role = ''
  }
}

export default {
  state,
  getters,
  actions,
  mutations
}
  1. 创建登录页面
<template>
  <div>
    <h2>Login</h2>
    <form>
      <div>
        <label for="username">Username:</label>
        <input type="text" id="username" v-model="username">
      </div>
      <div>
        <label for="password">Password:</label>
        <input type="password" id="password" v-model="password">
      </div>
      <button type="button" @click="login">Login</button>
    </form>
  </div>
</template>

<script>
import { mapActions } from 'vuex'

export default {
  data () {
    return {
      username: '',
      password: ''
    }
  },
  methods: {
    ...mapActions(['login']),
    async login () {
      try {
        await this.login({
          username: this.username,
          password: this.password
        })
        this.$router.push('/')
      } catch (err) {
        console.log(err)
      }
    }
  }
}
</script>

示例二:实现菜单控制

  1. 在Menu组件中使用v-if判断是否有对应权限
<template>
  <div>
    <ul>
      <li v-if="hasAccessRole('admin')"><router-link to="/dashboard">Dashboard</router-link></li>
      <li v-if="hasAccessRole('user')"><router-link to="/profile">My Profile</router-link></li>
    </ul>
  </div>
</template>

<script>
export default {
  methods: {
    hasAccessRole (role) {
      return this.$store.getters.getUserRole === role
    }
  }
}
</script>
  1. 后端需要提供接口供前端调用校验用户权限
app.get('/checkAccessRole', (req, res) => {
  if (req.headers.authorization === 'admin_token') {
    res.json({
      success: true,
      role: 'admin'
    })
  } else if (req.headers.authorization === 'user_token') {
    res.json({
      success: true,
      role: 'user'
    })
  } else {
    res.status(401).json({
      success: false,
      message: 'Unauthorized'
    })
  }
})

本文链接:http://task.lmcjl.com/news/15838.html

展开阅读全文