首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  程序员

前后端分离项目,你们是怎么控制权限的?

  •  1
     
  •   bobiscool · 2017-12-22 10:31:19 +08:00 · 18135 次点击
    这是一个创建于 392 天前的主题,其中的信息可能已经有所发展或是发生改变。

    已经做前后端分离 快一年了 技术栈趋向成熟

    • vue
    • vue router
    • vuex
    • node
    • express

    做出来的是单页面应用,但是在权限上一直都有问题。 现在我做权限 是 后台有一套,前端又有重复的一套,麻烦就在这里,

    • 只有我对后台有请求的时候,我才知道用户到底有没有这个权限「因为前台的权限,就存在 localSorage 里面,用户可以更改」,如果请求发现没权限,还是前端 router 跳到没权限或者登录页,但是如果这个页面没有请求呢。

    • 因为是一个管理系统,权限特别细,比如某些用户只有这几个目录可以看,其他用户只有那几个目录可以看,但我用的是前端路由,问题又来了。

      • 前端路由一般都是配置好的,我怎么让用户一进来就跳到他自己有权限的页面的第一页。
      • 如果用户直接输入 一个没有权限进入的地址 我该怎么拦截「须知我的拦截其实没有意义,因为页面都在他那里,他只需要改掉我的拦截代码就行」

    这里 我现在的解决方案是

    • 还是后台传给我 详细的权限,用于我铺设页面,如果这个没有权限,导航上也是没有显示的,但是这样还是可以被更改。
    • 用户登录 就会跳他能看到页面的第一个。
      • 首先 路由上 是全部都注册好的
      • 请求之后拿到权限,然后根据权限 生成导航数组
      • 然后自动页面跳到导航数组的 第一个
      • 切换页面的时候,都要去根据导航数组判断他是否有这个页面权限。

    但是我觉得自己的办法太笨拙,而且还是会被篡改,所以求各位解答疑惑,谢谢了。

    第 1 条附言  ·  2017-12-22 11:07:14 +08:00
    前面 「注意审题」说的有点不对 。。其实态度极其端正,只是有点着急,谢谢各位的 答复 。囧 rz
    43 回复  |  直到 2018-08-23 23:45:00 +08:00
        1
    lifeintools   2017-12-22 10:33:55 +08:00
    后端做鉴权。
        2
    sudoz   2017-12-22 10:34:16 +08:00
    必然是后端做啊
        3
    ty89   2017-12-22 10:38:20 +08:00
    后端维护一个权限的表(可能是在内存里,也可能是在数据库里),所有的权限设置都由这张表来控制,后端通过 API 返回给前端详细的权限配置,前端解析权限列表绘制界面,你跟后端约定一个两边都方便处理的数据结构就行了
        4
    bobiscool   2017-12-22 10:39:34 +08:00
    各位能不能 好好审题,权限是后台做,但是页面的权限后台怎么做? 特别是前后端分离后,路由是前端控制的时候。
        5
    Jealee   2017-12-22 10:40:19 +08:00
    后台传详细的权限,对应的 api 也会有权限控制啊,对于无权限的用户直接 401,前端再怎么改也获取不到数据啊。
        6
    CDL   2017-12-22 10:44:00 +08:00
    vue 组件请用异步加载
        7
    ctsed   2017-12-22 10:44:03 +08:00 via Android
    前端改就改了无所谓
        8
    ty89   2017-12-22 10:44:06 +08:00   ♥ 3
    @bobiscool
    看把你能得

    1,回答你的问题不是义务
    2,楼上几个都已经说的很清楚了,你自己稍微动一下脑子
    3,不做伸手党
        9
    sm0king   2017-12-22 10:46:19 +08:00   ♥ 1
    @ty89
    哈哈,“看把你能得 ” 这句说的真好。
    其实楼主只是把简单的问题想复杂了,很快就会反应过来了的。
        10
    bobiscool   2017-12-22 10:49:33 +08:00
    @ty89 这 。。。好吧 好像是 注意审题 说的不对 ,我其实态度很端正的 😂
        11
    Jealee   2017-12-22 10:50:53 +08:00   ♥ 1
    例如 A 菜单会访问 a,b,c 三个接口,B 菜单会访问 c,d,f 三个接口。后端维护几张权限表。前端获取用户信息时就会获取有哪些菜单的权限。比如甲用户只能访问 A 菜单,即使通过前端修改,他能弄出 B 菜单出来,显示 B 菜单的页面,但是对于后端我会判断他有没有 B 菜单的权限,没有的话 d,f 接口就会报 401,c 接口报不报 401 就看你的需求了。大概是这样子的,不知道讲明白没...
        12
    whypool   2017-12-22 10:52:28 +08:00
    做了 n 个 spa,给你一点意见:
    1,登陆权限,一般来说这个是独立出来,不用 spa 做,就一个表单的事情,后面也容易做扩展,包括单点登录什么的;
    2,登陆集成到 spa 里面,这个一般在请求加拦截,vuex 可以存 token,每次请求头带 token,后端校验 token 是否有效,如果修改了或者过期了,返回约定的字段标识,异步请求 axios 在返回 response 的时候优先拦截 token 校验,如果失效直接 vue-router 路由到登录页;
    3,内部权限,子页面什么的,前端一般是打包好了文件,页面是全部的,但是有的页面需要权限控制是否能访问,这时候只能做 2 次校验,后端返回当前权限能访问的路由 or 页面,存 vuex,前端路由加 watch,每次切换跳转都要遍历一次;
    4,接口权限,有的接口是不能提供给无权限的人使用的,比如抓包出来的;这时候后端做鉴权,返回约定的字段就行
        13
    wu67   2017-12-22 10:53:19 +08:00
    这个随便搜搜都能找到思路吧,rbac+前后端分离之类的。然后具体实现自己鼓捣鼓捣咯。。。
        14
    neoblackcap   2017-12-22 10:54:23 +08:00   ♥ 2
    @bobiscool 上面几楼已经说得很明白了,权限后台做,后台的为准。前端做的就是相信 API 里面获得的权限,至于会不会被用户串改,那个是用户的事。你要做的就是保证这个操作是这个用户做的,难道你还能防止 root 用户的信息不被人为泄露?
    如果你保证了前端的操作是这个用户做的,在正常的情况是不出问题的,那么剩下的都是后端的锅。研发服务端第一个准则就是不相信任何人,鉴权不通过就是失败,才不管请求是从哪里来。
        15
    hantsy   2017-12-22 10:56:07 +08:00
    还以为是 5 年前的帖子浮起来。现在 SPA 不要太常见,这还有什么好讨论的。

    手机 APP,SPA WEB 程序(不管是桌面还是网站)都是可以用 Oauth 2/JWT 认证。
        16
    corningsun   2017-12-22 10:56:11 +08:00   ♥ 2
    应该有后台管理系统吧?

    1. 维护页面菜单信息,名称,上下级关系,路由等;
    2. 维护 API 信息,API 的名称,路由;
    3. 维护菜单和 API 的对应关系;
    4. 维护角色信息,包括角色有哪些菜单权限;

    -----------------
    正常流:用户登陆后,根据角色返回菜单信息,并构造页面。
    异常流:用户自己输入菜单 URL,但是 API 调用时,后台会进行 角色校验如果没有对应 API 权限,会返回异常。
    -----------------
    关于菜单和 API 对应关系,建议前后端一起约定,根据相同的前缀可以模糊匹配,大大降低工作量。
        17
    freeminder   2017-12-22 10:58:08 +08:00   ♥ 2
    前端防止不了用户篡改去看越权的页面,这事情是服务端做的,接口上让他请求不到越权数据就好了,一个空页面的泄露也没什么可怕的,除非你把敏感数据写成静态资源了?所以你要是觉得前端的权限控制不够安全,你多虑了,这不是一个前端能做的事情。如果你的问题在于“同样的权限控制逻辑前后端在冗余”这种问题,那么这个控制逻辑必须维护在后端,因为之前已经说过了前端安全控制不现实。所以你要做的事情是请求这个控制数据,然后在 SPA 中应用这个控制。现在的做法就够用了。防篡改就保持一个思路:你做某个防范的代价低于破坏者的代价,就去做。安防就是一个权衡,在各种代价之中的均衡态,不要试图达成绝对安全。
        18
    LeeSeoung   2017-12-22 11:03:47 +08:00
    只要接口保证不被越权执行功能,前台就算被些懂行的绕过路由进去又会咋样。。反正他也只能在前台鼓捣,数据又不会记录到后台。
        19
    jasperjia   2017-12-22 11:07:47 +08:00
    路由 - 界面 - 接口 三层权限
        20
    jasperjia   2017-12-22 11:14:26 +08:00
    后端鉴权通过后返回前端,保存在全局的上下文中。在路由、界面、接口三部分加中间层判断是否具有权限。思路理清晰其实很简单。
        21
    skyadmin   2017-12-22 11:17:16 +08:00
    我觉得 18 楼说得对,你只要保证正常用户体验正常就行,没必要考虑会绕过路由进去的人,那波人就放他们在前端倒腾呗。
        22
    zachguo   2017-12-22 11:50:12 +08:00
    权限( role, permission )放在后端返回的 JWT token 里前端就能提取到了,前端再写一个 access control 的 HOC (我们用的 react )。
        23
    zachguo   2017-12-22 11:57:37 +08:00
    可以把用户权限管理完全独立成一个服务,前后端都需要验证 token,这样前后端重写、拆分都比较方便。
        24
    des   2017-12-22 12:37:08 +08:00 via Android
    你要觉得用户手工可以绕过的话,你可以路由部分后台生成完了传给你,权限敏感部分动态加载
        25
    xsown   2017-12-22 12:44:41 +08:00 via iPhone
    所有涉及到安全的都必须服务端鉴权,在 API 接口上做
        26
    RogerHzb   2017-12-22 12:45:49 +08:00
    做一个每个用户都能看的页面,所有人进来都跳这个页,轻松加愉快啊
        27
    duan602728596   2017-12-22 12:47:56 +08:00 via iPhone
    我做的项目都没有后台配合你,只能是前端自己控制模块是否渲染,后端验证什么的都是不存在的
        28
    110male   2017-12-22 13:08:26 +08:00
    统一调后端的接口。
        29
    klren0312   2017-12-22 13:20:19 +08:00
    后台把权限菜单发给前台 ,前台渲染菜单,然后请求的时候再判断接口权限
        30
    bramblex   2017-12-22 13:20:22 +08:00
    用户登录的时候顺便加载权限信息, 然后根据权限组配置一下菜单或者表单就好啊, 这不是基本操作嘛?
        31
    ooTwToo   2017-12-22 14:01:43 +08:00
    Component beforeCreate 的时候检查权限?
        32
    forzalianjunting   2017-12-22 14:09:13 +08:00
    建议还是用 vue-router 的 addRoutes 进行动态添加路由,最保险的方式
        33
    amibug   2017-12-22 17:02:36 +08:00
    前端通常会设计到大量的权限控制问题,按照细粒度归归类大致可以分类以下三类
    页面权限、模块权限-页面区块(组件)是否显示、元件权限-组件内元素是否显示
    对于传统的多页应用,页面权限控制不需要前端关心,后端路由做一层控制。在 SPA 架构的前端应用中,我们的思路是将所有的前端路由配置在后端,对于不同角色的用户,后端把路由列表吐给前端做路由注册。

    推荐看一下“前端权限控制方案” https://segmentfault.com/a/1190000011930560?_ea=3042426
        34
    AJian   2017-12-22 17:08:21 +08:00
    1. 后台接口加一层 api gateway 做权限控制,防止越权调用
    2. 请求后台接口获取当前登录用户所有的 [可用菜单(路由)] 及 [权限信息(权限 key )]
    3. 根据 [可用菜单] 动态生成 router
    4. 页面子控件,如按钮(对应权限 key )通过 v-if 实现显示与隐藏, 如
    <button @click="action" v-if="hasPermission('user.create')">新增用户</Button>
    hasPermission 做成一个 mixin 混入所有组件
        35
    zhx1991   2017-12-22 17:21:20 +08:00
    前端组件加载拉权限, 可以把没权限的模块都给不展示了

    后端拉各种数据和接口同样要拉权限
        36
    memorycancel   2017-12-22 20:06:51 +08:00
    不推翻重写留着过年???
        37
    yingfengi   2017-12-22 20:11:42 +08:00 via Android
    前后端双验证
        38
    lc4t   2017-12-22 20:42:10 +08:00
    RESTfulAPI 鉴权啊.. 不过有点时候出现一个问题,就是前端打包之后暴露了管理员用到的接口.

    后端 Nginx 上也可以设置一些白名单保证某些后台只允许 IP 访问..
        39
    PanJiaChen   2017-12-22 22:49:08 +08:00   ♥ 1
    我一直觉得前端和后端两个做权限的意义和目的是不同的。
    之前特意写过一篇文章,推荐可以起看看
    https://segmentfault.com/a/1190000009506097
        40
    abcbuzhiming   2017-12-22 23:57:35 +08:00   ♥ 1
    权限验证的目的是防止不怀好意的用户对系统进行渗透,修改不该它修改的数据,而前端的验证本质是做用户引导,代码都在别人前端那里,别人硬要通过修改达到绕过你的目的,你是防不住的,前端的验证仅仅是保证正常操作下用户看不到不该它看见的页面就行了,非正常用户跳过了你的限制,进入到不该进入的页面,这个页面还不是要从后端拉数据,后端的权限验证仍然能拦住它的。
        41
    Mutoo   2017-12-23 07:50:22 +08:00
    在 SPA 中前端所有子页面都是在客户端机子上的,前端路由的限制是为了体验,而不是安全。用户自己改了前端路由,能进到本来没有权限的子面页,但是他并没有接口权限获得数据,所以也没什么意义。
        42
    naixiaoxin   2017-12-23 19:26:04 +08:00 via iPhone
    通过接口返回菜单。然后业务接口加上权限控制就差不多了
        43
    hsluoyz   148 天前
    后端权限检查可以用 Casbin: https://github.com/casbin/node-casbin
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2303 人在线   最高记录 4236   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 20ms · UTC 02:18 · PVG 10:18 · LAX 18:18 · JFK 21:18
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1