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

前后端分离的项目,如何前端界面如何实现权限控制?

  •  1
     
  •   frozenway · 2020-01-15 15:40:56 +08:00 · 12261 次点击
    这是一个创建于 1808 天前的主题,其中的信息可能已经有所发展或是发生改变。

    以前 php 和 html 混合的代码,可以通过 php 权限控制函数来实现,但是前后端分离后,前端只通过 api 接口来获取数据,想来想去,每个页面几个功能,每个都调用一次 api 来确认一下是否有权限,服务器会不会扛不住?大家现在是怎样的思路?

    第 1 条附言  ·  2020-01-15 16:29:12 +08:00
    还有个问题就是用哪种语言去控制按钮或菜单的可见性?
    50 条回复    2020-02-02 17:22:44 +08:00
    slime7
        1
    slime7  
       2020-01-15 15:43:07 +08:00   ❤️ 4
    获取用户的时候返回权限不就行了,在前端做一套权限控制内容,请求后端的时候再用权限验证一下
    wednesdayco
        2
    wednesdayco  
       2020-01-15 15:43:08 +08:00
    有权限限制的接口负责鉴权……吧
    lihongjie0209
        3
    lihongjie0209  
       2020-01-15 15:44:58 +08:00   ❤️ 1
    这种东西肯定存全局啊, 不管是 vue 中的 vuex 或者是 基于浏览器的 storage, 只需要在登录的时候获取一下就好了.
    ylsc633
        4
    ylsc633  
       2020-01-15 15:46:13 +08:00
    权限真正的控制还是在服务端吧

    比如 一个菜单按钮! 某类用户不允许看到! 即使你前端控制了不让看!

    用户还是可以用其他方法去展示出来进行点击的!

    但是点击后! 会请求到服务端! 服务端肯定要校验权限的!

    简而言之! 前端做好权限相关的展示(比如菜单是否展示, 删除按钮是否可点等等 )就行了! 实际的操作(增删改查) 还是得服务端来校验
    frozenway
        5
    frozenway  
    OP
       2020-01-15 15:50:22 +08:00
    要是我说我后端用的是 thinkphp 的 auth 权限认证扩展,那用户登录时怎么返回用户拥有的权限,前端该如何实现?
    shintendo
        6
    shintendo  
       2020-01-15 15:53:28 +08:00
    首页获取当前用户角色 /权限,存全局,之后直接用,所有接口返回值用拦截器统一检查,无权限则提示或跳登录页
    权限检查在后端接口上做
    前端权限是做体验而不是做安全,所以覆盖常规使用场景即可
    Erroad
        7
    Erroad  
       2020-01-15 15:54:28 +08:00
    做一套权限表、用户表、用户权限表;
    做一个用户权限获取接口,前端缓存起来;
    前端根据用户权限展示功能入口,后端根据用户权限进行接口鉴权
    shintendo
        8
    shintendo  
       2020-01-15 15:57:46 +08:00
    @frozenway 一般总有个 getUserInfo 接口,在这里返回就行吧。前端就是加载首页(首个页面,不是 index )时调用这个接口
    tyrealgray
        9
    tyrealgray  
       2020-01-15 16:00:34 +08:00 via Android
    搞 JWT 不就行了吗?
    source
        10
    source  
       2020-01-15 16:02:17 +08:00
    一般会有一个单独的接口给出路由级别的权限控制,用来告诉前端 “能做什么”
    还会在其他接口上通过 jwt 之类的方式做权限检查,用来告诉前端 “不能做什么”
    frozenway
        11
    frozenway  
    OP
       2020-01-15 16:05:21 +08:00
    好的,感谢各位大佬
    NotFoundEgg
        12
    NotFoundEgg  
       2020-01-15 16:14:20 +08:00
    每个菜单 /按钮指定一个标识符 用 User_Menu 表关联起来(也可以中间插一层 Role 表)
    根据权限标识符接口获取当前用户全部资源的标识符
    根据标识符隐藏 /展示菜单 /按钮
    pinyue
        13
    pinyue  
       2020-01-15 16:17:29 +08:00
    权限最终是落在后端控制。
    前端只控制可见性
    est
        14
    est  
       2020-01-15 16:18:46 +08:00
    页面初始化的时候要返回一个可用权限列表

    甚至包含页面布局配置

    。。。

    。。。。

    。。。。。。

    然后你做着做着,就发现返回的页面配置 json 高度可定制

    甚至直接返回了渲染好的页面!

    full-circle.
    GaoGeYang
        15
    GaoGeYang  
       2020-01-15 16:31:13 +08:00
    你可以参考一下 vue-element-admin 它的做法。
    zhw2590582
        16
    zhw2590582  
       2020-01-15 16:33:41 +08:00
    可见性都是前端控制,现代流行框架会处理路由权限问题,假如细化到每个按钮的话那就麻烦一点,你说什么语言的话,那就是 js 了
    alex321
        17
    alex321  
       2020-01-15 16:34:37 +08:00
    你都前后端分离了,自然登录初始化用户信息的时候返回权限菜单,然后其他操作拉取和校验权限分配啊。
    sarices
        18
    sarices  
       2020-01-15 16:44:31 +08:00
    用户登录返回权限,前端根据权限做控制,后端根据用户做权限的控制
    aqqwiyth
        19
    aqqwiyth  
       2020-01-15 16:57:02 +08:00
    按钮级别的 点击&不可点击 / 隐藏&可见 每个按钮 /菜单之间有一个树的关联关系. 配置上资源与角色分离
    AyanamiRei
        20
    AyanamiRei  
       2020-01-15 17:32:59 +08:00
    fastadmin api 有这种验证, 建议看一下`
    OHyn
        21
    OHyn  
       2020-01-15 17:39:08 +08:00
    在路由的全局守卫里面做相关处理,动态创建权限相关的路由,参考 vue-element-admin
    cloudfstrife
        22
    cloudfstrife  
       2020-01-15 17:42:39 +08:00
    参考 RBAC 模型,需要对 RBAC 模型进行扩展。
    lbw
        23
    lbw  
       2020-01-15 21:35:17 +08:00
    https://github.com/lbwa/v-access/blob/master/README.CN.md 这是自己封装的一个基于 vue 和 vue-router 的权限库,可以试用一下
    jss
        24
    jss  
       2020-01-15 21:44:41 +08:00 via iPhone
    后端必须的权限验证+前端按钮级指令控制
    Juszoe
        25
    Juszoe  
       2020-01-15 21:57:36 +08:00
    我也有这个问题,看了这贴清爽多了
    admin7785
        26
    admin7785  
       2020-01-15 22:37:59 +08:00 via Android
    小白一个,上个项目做的就是权限模块。

    后端表里面是各种权限对应关系(用户-角色-功能-api ),根据 user 查询对应关系,没的话就没有权限~

    前端调接口判断是否隐藏页面
    Sendya
        27
    Sendya  
       2020-01-16 02:16:46 +08:00 via Android
    darknoll
        28
    darknoll  
       2020-01-16 08:26:16 +08:00
    这是个好问题
    whevether
        29
    whevether  
       2020-01-16 09:04:56 +08:00
    1: 菜单的数据由后端返回给前端。前端根据后端返回的权限菜单去显示。
    2: 控制权限路由和菜单路由的访问,通过后台返回的权限数据去匹配前端路由中额外定义的 meta 数据或自定义数据中的权限数据去控制
    3: 控制接口权限。每个接口约定书写规范。例如添加就 user/add,后台添加权限在中间件中拦截请求 url 地址去匹配 rbac 中的用户权限例如 a 用户是 user.add 权限,b 用户角色没有那么就没有就能控制接口权限了。
    4. 按钮级别权限。通过后端返回的权限数据在前端封装为一个指令集。通过指令去控制在指令内写逻辑. 例如 v-permission="user.add"
    whevether
        30
    whevether  
       2020-01-16 09:08:38 +08:00
    @tyrealgray 你 jwt 只是验证授权接口。你怎么控制不同角色的不同权限。还有按钮,如果我新增了一个角色。那不是又要在 jwt 授权上加上?
    TimPeake
        31
    TimPeake  
       2020-01-16 09:17:30 +08:00
    肯定是要后端控制得。前端只是辅助隐藏菜单 /控制路由权限
    hsk9044
        32
    hsk9044  
       2020-01-16 09:35:17 +08:00
    不用太担心服务器的承载量, 既然你的要请求业务接口, 肯定会有资源消耗的, 在请求内加一个权限控制的判断这个本身也不会对性能有什么影响. 再说了可以将用户的权限在登录的时候入一下缓存
    alertZ
        33
    alertZ  
       2020-01-16 09:45:23 +08:00
    这个我倒是做过。对于功能性按钮的话,分为前端后端两次校验,在用户点击按钮的时候,给出提示,若用户绕过前端校验,后端还可以根据用户传回的身份进行二次判断。
    对于界面菜单的话,可以做一个菜单权限的东西,在用户登录的时候,让后端根据用户身份级别返回响应的菜单回来,也就是你需要把你的菜单做出动态的。
    wanguorui123
        34
    wanguorui123  
       2020-01-16 09:56:35 +08:00
    返回权限列表,通过权限点隐藏对应的模块和按钮
    xmge
        35
    xmge  
       2020-01-16 09:58:33 +08:00
    前后端同时控制啊。

    前段控制不显示

    后端控制不可调用
    couashi
        36
    couashi  
       2020-01-16 10:13:08 +08:00
    每次都走网关鉴权
    pangleon
        37
    pangleon  
       2020-01-16 10:18:39 +08:00
    前端肯定要鉴权但是控制不住,后端是一定一定要卡死的
    netnr
        38
    netnr  
       2020-01-16 10:27:42 +08:00
    后台控制,也方便更新权限,根据登录用户实现同接口不同的数据
    wangyzj
        39
    wangyzj  
       2020-01-16 13:27:05 +08:00
    要维护一个权限表
    里面配置用户能访问的 api 和能访问的界面元素
    前端访问的时候对路由做劫持然后访问一个用户权限 api 来判断本页面权限和对应元素的显示状态
    参考 vue-element-admin
    Sapp
        40
    Sapp  
       2020-01-16 13:56:49 +08:00
    如果你想做到路由控制那很简单,路由钩子就能做,如果要通过模块就麻烦一些,我是用 babel 做的,大概就是需要判断权限的模块给模块的名字加个前缀(我是 React ),然后 babel 处理这些模块,收集一下这个组件调用的接口,统一给套个鉴权的包装组件,这样运行的时候这个鉴权组件会通过后端发过来的权限表查找是不是每个接口都满足,有一个不满足的就不给显示,满足就返回对应的 UI 组件,前端写代码的时候也不用特别关注这个,只需要在组件的名字做个标识就行。
    redbuck
        41
    redbuck  
       2020-01-16 17:03:29 +08:00
    第一步,整个 app 启动时,拉取用户信息.

    再就看你粒度做到多细了.
    页面级,前端路由都有相应的钩子,用进入页面前的钩子检查.
    按钮级,vuex 或者 redux 全局存储用户权限,然后搞一个高阶组件包装需要鉴权的按钮.

    当然,最要紧的还是后端,每个接口都通过 jwt 或者 cookie 鉴权即可.
    MaxTan
        42
    MaxTan  
       2020-01-16 17:05:39 +08:00
    不用另外调 api 确认权限,请求里面带上 token 就行了
    前端路由来控制页面
    vagranth
        43
    vagranth  
       2020-01-16 17:56:46 +08:00
    我的第一直觉是,用 keycloak
    Arisky
        44
    Arisky  
       2020-01-16 18:25:43 +08:00
    页面权限可以用路由保护来做。react 和 vue 都有。其他权限可以根据接口获取的权限树来做。
    不过需要注意的是,前端的权限控制的只是展示。后端接口一样需要做权限控制。
    ChefIsAwesome
        45
    ChefIsAwesome  
       2020-01-16 18:32:00 +08:00
    老生常谈的问题。你想想如果页面一直开着,直到身份过期。这时候前台能显示的是不是都显示了,如果后端不做验证,是不是毫无意义。
    guolaopi
        46
    guolaopi  
       2020-01-16 18:37:35 +08:00
    别纠结可见性了。。我记的 element-admin 里面是控制按钮是否渲染,而不是是否可见
    geeksun
        47
    geeksun  
       2020-01-17 08:11:03 +08:00
    在后端的 API 工程里增加 Interceptor 实现用户对访问 URL 权限的拦截,在前端实现比较鸡肋
    gengbo25hao
        48
    gengbo25hao  
       2020-01-17 09:45:19 +08:00
    vue+elementui 后端返回数据格式与 vue 路由参数格式一样,前端获取参数添加 this.$router.addRoutes(menuResolve);
    Achiii
        49
    Achiii  
       2020-01-17 09:48:31 +08:00
    你可以前端是一致的,请求某个功能的时候才判断有无权限
    chenhui7373
        50
    chenhui7373  
       2020-02-02 17:22:44 +08:00 via Android
    之前不知道的时候觉得一定有啥奇技淫巧,后面看了 jhipster 的文档,原来原理也是前端只做 ui 显示隐藏而已,真正权限在后端控制。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1024 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 19:20 · PVG 03:20 · LAX 11:20 · JFK 14:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.