前端面试必备——权限控制

2019-11-02 admin

clipboard.png

0.前言

记得当年面试的时候,面试官问我,前端怎么做权限控制,咱也不太会这个,只能尴尬回答道:“都是老大搭的架子,我只负责写业务模块代码”,😭😭😭。 如今自己也做了很多项目了,觉得有必有对前端权限控制做一个总结。

前端权限控制一直是前端必须掌握的一个知识点,一般来说稍微正规一点的后台系统肯定有权限控制。当然还是那句老话,前端本来就是不安全的,真正的安全还是需要后端兄弟去把关,所以后端也必须按做权限控制!我们前端的权限校验主要的目的是过滤不该有的请求和操作,减少服务端压力。

我个人认为前端权限控制应该分为四个方面,接口权限、按钮权限,页面权限,路由权限,下面就分四个部分探讨下权限控制怎么做

1.接口权限

原则

接口权限最简单,目前一般采用jwt的形式来验证,没有通过的话一般返回401 Authentication Required 登录完拿到Token,将token存起来(cookie或者ssessionStorage),每次登录的时候头部携带token就行了(axios请求拦截器实现)。

伪码实现

const {token} = login()
cookie.set('token',token)
axios.interceptors.request.use(config => {
        config.headers['token'] = cookie.get('token')
    return config
})

2.按钮权限

原则

一个页面会有新增,删除,编辑等等按钮。不同用户应该是有不同操作权限的。 我们不妨定义权限码 0:不可见 1:不可编辑 2:可编辑 我们提前和后端约定好按钮的名字,后端会返回一个按钮权限列表。然后我们根据权限列表使用v-if指令或者 绑定disabled属性达到相应权限效果。 当然更好的最好是自己写一个自定义权限指令,实质就是根据相应权限操作dom

伪码实现

比如概览页面的编辑按钮 名字先和后端定义好叫做overview-edit

// overviwe.vue  overview是概览页面的路由名
...
<button v-auth='edit'>
...
//util.js 全局注册自定义指令

Vue.directive('auth', {
    inserted: function (el, binding, vnode) {
        const optName = binding.arg
        const authName = `${routeName}-${optName}`     //这里根据路由名和操作类型拼出按钮名 overview-edit
        const btnAuthList = store.state.auth.btnAuthList
        if (btnAuthList[authName]===0) { // 按钮权限为0则移除dom
            el.parentNode.removeChild(el)
        } else if (btnAuthList[authName]===1) { // 按钮权限为1则禁用俺就
            vnode.componentInstance.disabled = true
        }
    }
})

// 登录的时候接受按钮权限并存在vuex里面
const {btnAuthList} = login()
vuex.state.btnAuthList = btnAuthList

3.页面权限(菜单权限)

个人任务页面权限实际上就是菜单权限,如果我们有去某个页面的导航菜单,那我是不是也就相应的没有去那个页面的权限了,所以说页面权限的实际就是菜单权限。

原则

一句话,获取菜单权限列表,动态递归生成菜单 这个菜单权限列表可以是后台直接返回你的,也可以是你注册路由的时候写在meta里面的菜单信息,后台返回路由权限,你根据meta信息动态算出的菜单权限。 至于菜单肯定是根据菜单权限递归生成的

伪码实现

//如果是定义在route信息里面会是这种样子
{
name:xxx
path:xxx
meta: {
        role: [xxx,xxx,xxx] //哪些角色有资格
        MenuIcon: 'xxxx'  //菜单图标
        MenuTitle: 'xxx' //菜单名
    }
}

//如果是直接获取菜单权限
const {menuList} = login()
//存vuex里
vuex.state.menuList = menuList
//在侧边栏或者顶部菜单组件里动态生成菜单
//这里基本都是用的UI库,比如element-ui的NavMenu来实现的,大家有兴趣可以自己看文档,当然也可以自己递归实现,不难
<navMenu/ :menuList=menuList>

4.路由权限

上面的菜单权限虽然做到能看不见菜单,但是我可以通过直接输入url的方式去没有权限的页面呀,这种情况实现上靠的是我们的路由权限来阻止。

原则

这里有两个方案 第一种,也是我目前项目用的,先注册好所有的路由,然后获取有资格访问的路由权限列表,最后直接通过Router.beforeEach来判断,每次跳路由的时候判断是否在权限列表里,在的话就放行,不在就提示权限不够 优点:简单暴力,不会跳到404页面 缺点:由于初始化了所有路由,可能代码有点冗余 第二种,先只注册基本路由,然后获取路由权限列表,然后借助route.add() API根据权限列表将有权限的路由动态注册到路由规则上 优缺点与第一种正好相反

伪码实现

这里只写第一种方案,第二种大家自行google

const {routeAuthList} = login()
cosnt whiteList = ['/login','/','/404']
//合并生成总路由
whiteList = whiteList.contact(routeAuthList)
//存vuex
vuex.state.whiteList = whiteList
//路由守卫判断
router.beforeEach((to, from, next) => {
    //权限校验
    let pass = whiteList.inclue(to);
    if(!pass){
        return console.log('无权访问');
    }
    next();
});

5.讨论

后端返回什么

这个我觉得实际没有定论,相关的文章也读了许多,什么做法都有,还是需要结合实际业务。 比如 1.按钮权限特别少的,那么后端不用返回按钮权限,直接前端生成钮权限就行。甚至不用使用自定义指定,直接v-if,disable就行 2.权限页面特别多,次级路由也特别多,那么也可以前端这边生成路由权限,因为如果后端返的话,每次定义一个次级页面都得让后端在数据库加一条数据,太麻烦人了,不方便 3.后端也不是说非得返回权限路由列表的,像我目前的项目就是返回的菜单列表,然后我根据菜单列表名手动算出权限列表。其实都一样,返回权限列表也是根据权限列表里面的meta算出菜单列表,有毛区别?

缓存什么

关于缓存,大家可以看我这篇文章缓存 获取的个人信息(包括权限列表)该不该缓存到ssessionStorage里面?我看很多人的文章都是只缓存token,每次刷新都是重新拉取信息。 个人认为这样做意义不大,缓存的目的就是为了减少请求,优化交互。存在当前页签基本能保证同一时间你就是你。再说防君子不防小人,至于真的是小人,篡改ssessionStorage数据,咱不是还有后台兄弟的校验吗,怕个卵。

6.总结

总结了前端所有的权限控制,并给出了相应的伪码实现,希望能给大家带来应该的帮助

[转载]原文链接:https://segmentfault.com/a/1190000020887109

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-78781.html

文章标题:前端面试必备——权限控制

相关文章
前端工程师应该具备的三种思维
如果你是一个天才等级的工程师(马上可以离开),可以独立完成一个很多事情,你可以是一个怪咖,因为我相信没有一个人不会不佩服你。但现实归现实,多数人都不是天才,而我们在职场上也不是单打独斗,我们需要团队合作,需要协调和配合,需要考虑除了代码以外...
2016-01-13
前端开发领域推荐关注的微信公众号
这篇文章分享了前端领域的多个值得关注的技术、设计、极客、创业相关微信公众号。其中有最受欢迎的热门公众号、也有专注某个技术或设计的公众号,涵盖:算法、JavaScript、Nodejs、程序员、Web前端、Linux、数据库、创业、UI设计和...
2017-03-23
前端单页应用微服务化解决方案2 - Single-SPA
技术选型 经过各种技术调研我们最终选择的方案是基于 Single-SPA 来实现我们的前端微服务化. Single-SPA 一个用于前端微服务化的JavaScript前端解决方案 使用Single-SPA之后,你可以这样做: (兼容各...
2018-09-07
五个值得尝试的前端开发工具
在过去的几年时间里,出现了许多全新的网页应用程序,不过,由于应用程序的功能越来越丰富,也导致了前端开发的复杂度大幅增加。 现在也有不少前端开发工具,比如Backbone和EmberJS框架都能提供稳定的App开发解决方案。同时,Javasc...
2015-12-23
12个Web设计师必备的Bootstrap工具
作为一位设计师,会经常追寻新鲜有趣的设计工具,这些工具会提高工作的效率,使得工作更有效, 最重要的是使工作变得更方便。非常肯定的说,随着日益增长的工具和应用的数量,设计和开发变得越来越简单了。其中最普遍使用的最终框架 之一是 Bootstr...
2015-12-24
ES6笔试面试题总结
收集整理的一些ES6的笔试面试题,出处在最底部标明 把以下代码使用两种方法,来依次输出0到9? var funcs = [] for (var i = 0; i &lt; 10; i++) { funcs.push(functi...
2018-04-22
如何用js 实现依赖注入的思想,后端框架思想搬到前端来
大家在做些页面的时候,很多都是用ajax实现的,在显示的时候有很多表单提交的add或者update操作,显然这样很烦,突然想到了一个比较好的方法,下面给大家分享下如何用js 实现依赖注入的思想,后端框架思想搬到前端来。 应用场景: 前后端一...
2017-03-29
javascript控制图片播放的实现代码
一般实现用鼠标控制图片的滚动效果都比较麻烦,大段大段的代码让新手头疼无从下手,下面我来写个简单的javascript控制图片滚动的效果。代码简洁明了,兼容ie、firefox和google浏览器。 分享代码如下: &lt;!DOCTYPE ...
2017-03-29
javascript实现控制文字大中小显示
部分网站内容页通常会看到有控制文字分别以 大,中,小 三种方式显示,下面就把这个小功能做一下记录,对提高网站用户体验度还是有一些帮助的哦! &lt;html&gt; &lt;head&gt; &lt;meta http-equiv=&q...
2017-03-23
Vue.js bootstrap前端实现分页和排序
写之前先抱怨几句。本来一心一意做.net开发的,渐渐地成了只做前端。最近项目基本都用java做后台,我们这些.net的就成了前端,不是用wpf做界面,就是用html写web页面。 深知自己前端技术不足,以前虽说用asp.net前后台都做,但...
2017-03-14
回到顶部