在前后端分离的项目中,前端视图权限需要和后端权限体系保持同步,避免用户访问无权限的页面或操作。Django内置的Groups功能可以方便地对用户进行分组并分配对应权限,我们可以基于这个能力实现Vue应用的前端视图权限管理。

后端Django权限配置与接口开发
首先需要在Django中配置用户分组和权限,然后提供接口给前端获取当前用户的权限信息。假设我们已经有基础的Django用户系统,先创建对应的分组并分配权限:
# Django后台创建分组并分配权限示例 from django.contrib.auth.models import Group, Permission from django.contrib.contenttypes.models import ContentType from your_app.models import YourModel # 替换为你的业务模型 # 创建管理员分组 admin_group, created = Group.objects.get_or_create(name='admin') # 获取模型的查看权限 content_type = ContentType.objects.get_for_model(YourModel) view_permission = Permission.objects.get(codename='view_yourmodel', content_type=content_type) # 将权限分配给管理员分组 admin_group.permissions.add(view_permission)
接下来开发两个核心接口,一个用于获取当前登录用户的所有权限,一个用于获取用户所属的分组:
# views.py 接口代码
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.contrib.auth.models import Group, Permission
@login_required
def get_user_permissions(request):
user = request.user
# 获取用户所有权限的codename
permissions = user.get_all_permissions()
return JsonResponse({'permissions': list(permissions)})
@login_required
def get_user_groups(request):
user = request.user
groups = user.groups.values_list('name', flat=True)
return JsonResponse({'groups': list(groups)})
配置对应的路由,确保前端可以访问这两个接口:
# urls.py 路由配置
from django.urls import path
from . import views
urlpatterns = [
path('api/user/permissions/', views.get_user_permissions, name='user-permissions'),
path('api/user/groups/', views.get_user_groups, name='user-groups'),
]
Vue前端权限状态管理
在Vue项目中,我们需要先获取用户的权限和分组信息,存储到全局状态中,方便后续各个组件和路由使用。这里使用Vuex进行状态管理:
// store/modules/auth.js
import axios from 'axios'
const state = {
permissions: [],
groups: []
}
const mutations = {
SET_PERMISSIONS(state, permissions) {
state.permissions = permissions
},
SET_GROUPS(state, groups) {
state.groups = groups
}
}
const actions = {
// 获取用户权限和分组信息
async fetchUserAuth({ commit }) {
try {
const [permRes, groupRes] = await Promise.all([
axios.get('/api/user/permissions/'),
axios.get('/api/user/groups/')
])
commit('SET_PERMISSIONS', permRes.data.permissions)
commit('SET_GROUPS', groupRes.data.groups)
} catch (error) {
console.error('获取用户权限失败', error)
}
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
在Vue实例初始化的时候,调用获取权限的action,确保权限数据提前加载:
// main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'
new Vue({
store,
created() {
// 如果用户已登录,获取权限信息
if (store.state.user.isLogin) {
this.$store.dispatch('auth/fetchUserAuth')
}
},
render: h => h(App)
}).$mount('#app')
Vue路由权限控制
使用Vue Router的全局前置守卫,在路由跳转前校验用户是否有访问目标路由的权限。我们可以给路由配置meta字段,标记该路由需要的权限或分组:
// router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import store from '../store'
Vue.use(VueRouter)
const routes = [
{
path: '/admin/dashboard',
name: 'AdminDashboard',
component: () => import('../views/AdminDashboard.vue'),
meta: {
requireGroup: 'admin' // 需要admin分组才能访问
}
},
{
path: '/user/profile',
name: 'UserProfile',
component: () => import('../views/UserProfile.vue'),
meta: {
requirePermission: 'view_yourmodel' // 需要对应权限才能访问
}
},
{
path: '/login',
name: 'Login',
component: () => import('../views/Login.vue')
}
]
const router = new VueRouter({
mode: 'history',
routes
})
// 全局前置守卫
router.beforeEach((to, from, next) => {
// 不需要权限的路由直接放行
if (!to.meta.requireGroup && !to.meta.requirePermission) {
next()
return
}
// 未登录跳转到登录页
if (!store.state.user.isLogin) {
next('/login')
return
}
// 校验分组权限
if (to.meta.requireGroup) {
const userGroups = store.state.auth.groups
if (userGroups.includes(to.meta.requireGroup)) {
next()
} else {
next('/403') // 无权限跳转到403页
}
return
}
// 校验具体权限
if (to.meta.requirePermission) {
const userPermissions = store.state.auth.permissions
if (userPermissions.includes(to.meta.requirePermission)) {
next()
} else {
next('/403')
}
return
}
})
export default router
Vue组件内权限控制
除了路由级别的权限控制,我们还需要在组件内部控制某些按钮、模块的显隐,比如只有管理员分组才能看到删除按钮。可以使用自定义指令或者计算属性实现:
自定义权限指令实现
创建一个全局自定义指令,根据用户的权限或分组控制元素显隐:
// directives/permission.js
import store from '../store'
export default {
inserted(el, binding) {
const { value } = binding
const userGroups = store.state.auth.groups
const userPermissions = store.state.auth.permissions
// 支持分组校验和权限校验两种模式
if (value.group) {
if (!userGroups.includes(value.group)) {
el.parentNode && el.parentNode.removeChild(el)
}
}
if (value.permission) {
if (!userPermissions.includes(value.permission)) {
el.parentNode && el.parentNode.removeChild(el)
}
}
}
}
在main.js中注册这个自定义指令:
// main.js
import Vue from 'vue'
import permissionDirective from './directives/permission'
Vue.directive('permission', permissionDirective)
在组件中使用这个指令控制元素显隐:
<template>
<div>
<h2>用户管理页面</h2>
<!-- 只有admin分组能看到删除按钮 -->
<button v-permission="{ group: 'admin' }">删除用户</button>
<!-- 只有有view_yourmodel权限的用户能看到详情按钮 -->
<button v-permission="{ permission: 'view_yourmodel' }">查看详情</button>
</div>
</template>
计算属性控制显隐
也可以使用计算属性结合v-if实现权限控制:
<template>
<div>
<h2>数据列表</h2>
<table>
<tr>
<th>名称</th>
<th>操作</th>
</tr>
<tr v-for="item in list" :key="item.id">
<td>{{ item.name }}</td>
<td>
<button v-if="canEdit">编辑</button>
</td>
</tr>
</table>
</div>
</template>
<script>
export default {
data() {
return {
list: []
}
},
computed: {
canEdit() {
return this.$store.state.auth.groups.includes('admin')
}
}
}
</script>
注意事项
- 前端权限控制只是辅助,所有涉及数据操作的接口必须在Django后端再次校验权限,避免用户绕过前端直接请求接口。
- 用户权限或分组更新后,需要重新获取前端的权限状态,保证权限数据同步。
- 路由meta的权限配置需要和Django后端的权限codename保持一致,避免匹配失败。
Django_GroupsVue前端视图权限权限管理修改时间:2026-06-28 06:57:44