600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > vue-element-adminn实现权限管理(后端只控制权限roles)

vue-element-adminn实现权限管理(后端只控制权限roles)

时间:2023-08-07 00:06:22

相关推荐

vue-element-adminn实现权限管理(后端只控制权限roles)

用户应该分为三类:

​ 1、普通用户(user):只允许登录前台小程序端并进行基本的操作、不能进行后台管理系统的任何操作。

​ 2、店铺管理员(admin):允许管理店铺的栏目CRUD操作、商品CRUD操作、评论的查看与删除、查看店铺的销售情况等。

​ 3、超级管理员(super):允许进行店铺管理和用户管理等操作、能查看系统的用户数和店铺数等基本统计。

具体实现

创建vue实例的时候将vue-router挂载,但这个时候vue-router挂载一些登录或者不用权限的公用的页面。当用户登录后,获取用户roles,将roles和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表。调用router.addRoutes(store.getters.addRouters)添加用户可访问的路由。使用vuex管理路由表,根据vuex中可访问的路由渲染侧边栏组件。

代码层面:

1. 普通用户登录拒绝访问后端:

vue前端:

//用户登录获取tokenlogin({commit }, userInfo) {const {phone, userPassword } = userInforeturn new Promise((resolve, reject) => {login({phone: phone.trim(), userPassword: userPassword.trim(),method: 1 }).then(response => {//method 为一时代表是登录后台管理系统const {data } = responsecommit('SET_TOKEN', data.token)setToken(data.token)resolve()}).catch(error => {reject(error)})})},

controller:

@PostMapping("/login")public Result login(@RequestBody User user){if(user.getMethod() == 1){//为后台发出的登录请求,需要检验权限String roles = userService.findUserByPhone(user.getPhone()).getRoles();if(roles.equals("user")){//普通用户,阻止登录后台return Result.error().message("您没有足够的权限");}}......省略了其它登录处理代码

2. admin(店铺管理员) 与 super(超级管理员) 不同身份登录能提供不同路由

1.后端返回的用户对象(必须携带roles字段):
2. vue-element-admin处理:

vue-element-admin登录并改变路由的开始:

import router from './router'import store from './store'import {Message } from 'element-ui'import NProgress from 'nprogress' // progress barimport 'nprogress/nprogress.css' // progress bar styleimport {getToken } from '@/utils/auth' // get token from cookieimport getPageTitle from '@/utils/get-page-title'NProgress.configure({showSpinner: false }) // NProgress Configuration//白名单const whiteList = ['/login'] // no redirect whitelistrouter.beforeEach(async(to, from, next) => {// start progress barNProgress.start()// set page titledocument.title = getPageTitle(to.meta.title)//获取token// determine whether the user has logged inconst hasToken = getToken()if (hasToken) {//是否为登录if (to.path === '/login') {//去首页next({path: '/' })NProgress.done()} else {//从vuex中获取权限const hasRoles = store.getters.roles && store.getters.roles.length > 0if (hasRoles) {//如果存在则放行next()} else {try {//roles 必须是一个数组//获取用户信息和权限信息,存到vuex中const {roles } = await store.dispatch('user/getInfo')//生产路由数据const accessRoutes = await store.dispatch('permission/generateRoutes', store.getters.roles)//const accessRoutes = []// dynamically add accessible routesrouter.addRoutes(accessRoutes)var tempRoutes = router.options.routes.slice(0,3).concat(accessRoutes); //将原路由侧边栏显示截取为初始三个(作者其实不支持这样)router.options.routes = tempRoutes; //将路由添加到侧边栏(作者其实不支持这样)// hack method to ensure that addRoutes is complete// set the replace: true, so the navigation will not leave a history recordnext({...to, replace: true })} catch (error) {// remove token and go to login page to re-loginawait store.dispatch('user/resetToken')Message.error(error || 'Has Error')//next(`/login?redirect=${to.path}`)next({path: '/' })NProgress.done()}}}} else {/* has no token*/if (whiteList.indexOf(to.path) !== -1) {// in the free login whitelist, go directlynext()} else {// other pages that do not have permission to access are redirected to the login page.next(`/login?redirect=${to.path}`)NProgress.done()}}})router.afterEach(() => {// finish progress barNProgress.done()})

关键的处理函数(getInfo、generateRoutes)在store/文件目录下:

store/modules/permission.js:

const actions = {generateRoutes({commit }, roles) {return new Promise(resolve => {//存的是有权限的路由,是一个数组let accessedRoutesif (roles.includes('admin')) {accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)} else {accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)}//commit('SET_ROUTES', accessedRoutes)resolve(accessedRoutes)})}}......部分代码

store/modules/user.js:

//获取用户信息getInfo({commit, state }) {return new Promise((resolve, reject) => {//调用api/user里面的接口getInfo(state.token).then(response => {const {data } = responseif (!data) {return reject('Verification failed, please Login again.')}const user = data.user//console.log(user);commit('SET_NAME', user.username)commit('SET_AVATAR', user.headImg)var temp_roles = [user.roles]; //vue-element-admin里面roles必须为数组//console.log(temp_roles);commit('SET_ROLES', temp_roles) //设置权限resolve(data)}).catch(error => {reject(error)})})},......部分代码

router/index.js

import Vue from 'vue'import Router from 'vue-router'Vue.use(Router)/* Layout */import Layout from '@/layout'/*** Note: sub-menu only appear when route children.length >= 1* Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html** hidden: true if set true, item will not show in the sidebar(default is false)* alwaysShow: trueif set true, will always show the root menu* if not set alwaysShow, when item has more than one children route,* it will becomes nested mode, otherwise not show the root menu* redirect: noRedirect if set noRedirect will no redirect in the breadcrumb* name:'router-name' the name is used by <keep-alive> (must set!!!)* meta : {roles: ['admin','editor'] control the page roles (you can set multiple roles)title: 'title'the name show in sidebar and breadcrumb (recommend set)icon: 'svg-name'/'el-icon-x' the icon show in the sidebarbreadcrumb: false if set false, the item will hidden in breadcrumb(default is true)activeMenu: '/example/list' if set path, the sidebar will highlight the path you set}*//*** constantRoutes* a base page that does not have permission requirements* all roles can be accessed* 不需要权限就可以访问的路由*/export const constantRoutes = [{path: '/login',component: () => import('@/views/login/index'), // “@”指的是src目录hidden: true},{path: '/404',component: () => import('@/views/404'),hidden: true},{//侧边栏主页路由path: '/',component: Layout,redirect: '/dashboard',children: [{path: 'dashboard',name: 'Dashboard',component: () => import('@/views/dashboard/index'),meta: {title: '主页', icon: 'dashboard' }}],}]//异步挂载的路由//动态需要根据权限加载的路由表export const asyncRoutes = [{//侧边栏用户管理页路由path: '/user',component: Layout,redirect: '/user',children: [{path: 'user',name: 'User',component: () => import('@/views/user/user'),meta: {title: '用户管理', icon: 'user', roles: ['super'] }}]},{//侧边栏店铺管理页路由path: '/store',component: Layout,redirect: '/store',children: [{path: 'store',name: 'Store',component: () => import('@/views/store/store'),meta: {title: '店铺管理', icon: 'shopping', roles: ['super'] }}]},{//侧边栏发布管理页路由path: '/commondity',component: Layout,redirect: '/commondity/column',name: 'Commodity',meta: {title: '发布管理', icon: 'edit',roles: ['admin']},children: [{path: 'column',name: 'Column',component: () => import('@/views/column/column'),meta: {title: '栏目管理', icon: 'list',roles: ['admin'] }},{path: 'product',name: 'Product',component: () => import('@/views/product/product'),meta: {title: '商品管理', icon: 'money',roles: ['admin'] }},]},{//侧边栏订单管理页路由path: '/order',component: Layout,redirect: '/order/order',name: 'Order',meta: {title: '订单管理', icon: 'clipboard',roles: ['admin']},children: [{path: 'history_order',name: 'history_Order',component: () => import('@/views/order/order'),meta: {title: '历史订单管理', icon: 'skill',roles: ['admin'] }},{path: 'receive_order',name: 'Receive_order',component: () => import('@/views/receive_order/receive_order'),meta: {title: '接单管理', icon: 'people',roles: ['admin'] }},]},{//侧边栏评论管理页路由path: '/comment',component: Layout,redirect: '/comment',children: [{path: 'comment',name: 'Comment',component: () => import('@/views/comment/comment'),meta: {title: '评论管理', icon: 'message',roles: ['admin'] }}]},{path: 'external-link',component: Layout,children: [{path: '/x_y_king/master-goose',meta: {title: '项目地址', icon: 'link'}}]},{path: '*', redirect: '/404', hidden: true }];const createRouter = () => new Router({// mode: 'history', // require service supportscrollBehavior: () => ({y: 0 }),routes: constantRoutes})const router = createRouter()// Detail see: /vuejs/vue-router/issues/1234#issuecomment-357941465export function resetRouter() {const newRouter = createRouter()router.matcher = newRouter.matcher // reset router}export default router

3. 可以参考B站视频:

B站—vue-element-admin权限验证流程讲解

vue后台管理不同权限路由实现方式:

通过获取当前用户的权限去比对路由表,生成当前用户具有的权限可访问的路由表,通过router.addRoutes动态挂载到router上。

权限控制的主体思路,前端会有一份路由表,它表示了每一个路由可访问的权限。当用户登录之后,通过token获取用户的role,动态根据用户的role算出其对应有权限的路由,再通过router.addRoutes动态挂载路由。但这些控制都只是页面级的,说白了前端再怎么做权限控制都不是绝对安全的,后端的权限验证是逃不掉的。现在就是前端来控制页面级的权限,不同权限的用户显示不同的侧边栏和限制其所能进入的页面(也做了少许按钮级别的权限控制),后端则会验证每一个涉及请求的操作,验证其是否有该操作的权限,每一个后台的请求不管是 get 还是 post 都会让前端在请求header里面携带用户的token,后端会根据该token来验证用户是否有权限执行该操作。若没有权限则抛出一个对应的状态码,前端检测到该状态码,做出相对应的操作。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。