Iview-admin: 方便写一个根据后台数据控制权限的么?

Created on 22 Nov 2017  ·  22Comments  ·  Source: iview/iview-admin

权限后台来控制,动态路由来实现,给个思路也可以

feature

Most helpful comment

动态路由的实现本身比较简单,后台给到路由数据,前端处理数据得到实际路由,然后addRouters就行了。解决刷新问题有两种做法,一种是路由数据持久化,另一种是刷新重新获取路由数据,各有优劣,通常还是刷新重新获取吧,这样权限变更了前端不需要重新登录,刷新一下就行了。
详细的实现过程参考这里:http://refined-x.com/2017/09/01/%E7%94%A8addRoutes%E5%AE%9E%E7%8E%B0%E5%8A%A8%E6%80%81%E8%B7%AF%E7%94%B1/

All 22 comments

我是直接后台取菜单,数据格式

private String id;

    private String parentid;
    /**
     * 路由名称
     */
    private String name;
    /**
     * 路由路径
     */
    private String path;
    /**
     * 菜单显示名称
     */
    private String title;
    /**
     * 图标
     */
    private String icon;

    private List<VueMenuDto> children = Lists.newArrayList();

取到以后直接调用store.commit("setMenuList");

@swit1983 取到之后怎么动态添加到路由去呢?store.commit("setMenuList")的用法不是很懂。我尝试添加了,说路由是只读的。然后我用addRouters添加,会报错。真心请教你的解决方案。最好把思路详细说一下。我昨天搞了一天也没弄好,快疯了。

@dolphinfine 路由都是定义好的啊,不用加。后台定义的只是菜单,只要保证name一致就可以了

@swit1983 看来你跟我的解决方案是一样的,只是这样会出现一个问题:路由是写死的,菜单是动态的,如果用户知道路由,直接访问路由地址还是可以访问的。如果动态加载路由就不存在这个问题。

js 你还想完全控制权限啊!就算你动态加路由还是不行的,还是后台控制吧。

我觉得最好的解决方案还是动态路由,我还得继续研究下怎么用。

其实iview-admin做了处理,如果用户没有权限,即便是在地址栏直接输入地址也无法访问没有权限浏览的页面

我现在在mian.js 写了这么一段,登录时取权限写在sessionStorage,然后添加路由,现在遇到两个问题,1:为什么第一次登录进来菜单没出来,重新刷新就有菜单了。
2:点击左侧菜单可以出来,上面的地址栏也变了,再刷新又找不到页面了
let data = JSON.parse(window.sessionStorage.getItem('power'));
if (data) {
let routes = [];
MenuUtils(routes, data);
appRouter.push(...routes);
router.addRoutes(routes);
}

@guowangsheng 动态添加路由要重新跳转一次:

router.addRoutes(res.data)
next({ ...to }) // 重新跳转一次,这样会采用新挂载的 router

贴下我的解决方案,不是很好,但是可以作为过渡方案使用一下:
1.首先,登录成功获取当前用户可以显示的菜单。
2.获取到这个菜单之后this.$store.commit('updateMenulist',showMenu);
3.可以看到updateMenulist这个mutation我增加了参数menuItem。具体修改如下
image
获取到可以显示的菜单之后,把这个就存到本地,这是非常关键的,必须要持久化,不然刷新又没了。然后appRouter.forEach改成menuItem.forEach,appRouter是所有菜单,是只读的不能修改。menuItem是需要显示的菜单。这样修改之后菜单就你让他显示几个就显示几个。
4.然后还有一处需要修改,就是根组件mounted的时候,这里会确保刷新后菜单依然不变。
image
我的版本是比较老的,大家可以根据这个思路自行修改。说下缺点:

这里路由是写死的,菜单是动态的,如果后台不做权限控制或者没有做好,用户知道地址依然可以访问,这是个很大的安全隐患。

还有更好的解决方案欢迎讨论。

动态路由的实现本身比较简单,后台给到路由数据,前端处理数据得到实际路由,然后addRouters就行了。解决刷新问题有两种做法,一种是路由数据持久化,另一种是刷新重新获取路由数据,各有优劣,通常还是刷新重新获取吧,这样权限变更了前端不需要重新登录,刷新一下就行了。
详细的实现过程参考这里:http://refined-x.com/2017/09/01/%E7%94%A8addRoutes%E5%AE%9E%E7%8E%B0%E5%8A%A8%E6%80%81%E8%B7%AF%E7%94%B1/

分享一下我的解决方法, 前端路径是直接定义在客户端js文件中的. 通过用户的权限隐藏相关的菜单. 权限是由服务器控制的, 不管实现是动态路径还是静态的, API都必须要进程权限校验, 才能达到权限控制的目的.

  1. app.vue中获取当前登录用户的权限信息
mounted() {
    axios.get(`/api/admins/user/root`).then(response => {
        this.$store.commit('updateMenulist', email === response.data.root);
    });
}
  1. 将不具备权限的菜单隐藏不显示
mutations: {
    updateMenulist(state, root) {
        var menus = [];
        if (root) {
            menus = appRouter;
        } else {
            appRouter.forEach((v) => {
                if (!v.root) {
                    menus.push(v)
                }
            });
        }
        state.menuList = menus;
    }
}

我这个权限功能本身就非常简单, 只分用户/超级用户, 所以实现也比较简单, 只是简单的做了一个用户权限校验. 当然要做到更加细致, 我觉得只需要在 router 中将权限的关系映射好就行了, 在菜单渲染前做一个递归取出有权限的菜单.

前端只需要做菜单的展示与隐藏, 实际的权限控制还是要在API做.

如何由后台通过传输json来完全控制用户的菜单显示呢?不只是控制菜单显示和隐藏,包括图标、链接、文字等等

那样每次改动路由都要去后端做改动,太麻烦了。后台会打你的

@dolphinfine 打不打不知道,我就是后台。。。。。因为某种情况需要我这么做,我觉得如果后台控制不了,每次都得改源码更新,我觉的这个操作没有后台修改来的方便快捷。。。。非开发人员也可以操作

最后页面先加载权限菜单 ,菜单后台提供的,路由也就是后台控制的

@sowork 我的方案可以实现哦,将自定义信息放进权限信息里前端动态生成路由的同时,可以根据自定义信息输出图标和文字,但路由地址就不能改了,因为路由地址对应着前端组件。
https://github.com/tower1229/Vue-Access-Control

@guowangsheng 请问你动态路由搞定了吗? 能不能借鉴一下? 我现在也是做这个 首次登陆进去能新加的路由能正常跳转,但是一刷新路由就跳不过去了?请问你刷新那部分是怎么处理的

@acecea 我在main.js又写了个调用权限的接口,这样刷新就还在了

用了当前最新的版本,提供了路由权限过滤,配置方法是给路由加一个属性access;app.js中的updateMenulist方法会过滤路由,关键的问题在于,access的值是什么呢?应该根据需求来配置才比较科学;查看了updateMenulist方法,用于过滤权限的变量为accessCode,其值为:let accessCode = parseInt(Cookies.get('access')); , 于是,我将此值根据项目需求做了修改,对应页面路由加对应的access属性值。

其他想法:我的项目权限区分比较简单,A类管理员和B类管理员,将其页面路由分开写,aRouter和bRouter,完全重新改写updateMenulist方法,若为A管理员,则将aRouter的值赋给menuList.

请教大家:

  1. 如果需要不同权限的用户有不同的首页,大家是怎么做,我看iview-admin源码很多地方都是默认写了home_index, 但每个路由只能有唯一的name, 不能重名,是否意味着要根据自己的需求改写这些地方;
  1. 若是不想要这个固定打开的首页,也是要自己改写这些地方吧

=====
更新:打扰了,已根据需求改写面包屑导航和标签栏的初始值和mutation

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Miku-Zeng picture Miku-Zeng  ·  3Comments

zhangyaguang-aimm picture zhangyaguang-aimm  ·  4Comments

zhangwei900808 picture zhangwei900808  ·  5Comments

xinmowen picture xinmowen  ·  4Comments

330132662 picture 330132662  ·  4Comments