权限与访问控制

作者:weixin79893765432...日期:2026/1/2

目录

  • 一、概念
  • 二、权限与访问控制的「能力全景图」
  • 三、前端视角的「权限控制分层模型」(核心)
    • 1、登录态层(Authentication State)
    • 2、路由层(Page Access Control)
    • 3、菜单层(Navigation Control)
    • 4、组件 / 操作层(Action Control)
  • 四、前端权限系统的“典型数据流”
  • 五、权限模型的三种常见设计(前端必须懂)
    • 1、RBAC(基于角色)
    • 2、PBAC(基于权限点)
    • 3、ABAC(基于属性/规则)
  • 六、重点「权限与访问控制」业务剖析
    • 1、用户鉴权
      • (1)、用户鉴权概念
        • (2)、用户鉴权的「标准模型」(企业级通用)
        • (3)、主流鉴权方案全景对比(你必须会)
        • (4)、JWT 鉴权机制(前端必须吃透)
          • ①、JWT 本质
            * ②、企业级 JWT 设计(重点)
        • (5)、前端如何“正确”做用户鉴权(分层讲)
          • ①、登录阶段(Login)
            * ②、凭证存储(非常关键)
            * ③、请求鉴权(Request Authentication)
            * ④、过期处理(企业级重点)
        • (6)、一个「简单但完整」的企业级典例
          • ①、登录流程
            * ②、前端核心代码(示意)
            * ③、后端核心原则(前端要懂)
    • 2、黑白名单
      • (1)、黑白名单概念
        • (2)、黑白名单在系统中的“正确位置”
        • (3)、黑白名单的业务分类(前端必须理解)
          • ①、按“对象”分类
            * ②、按“作用方式”分类
        • (4)、前端在黑白名单中的真实职责(重点)
        • (5)、企业级黑白名单的“数据模型”(你要会看)
        • (6)、前端如何“正确”使用黑白名单(分层讲)
          • ①、初始化阶段(登录后)
            * ②、菜单 / 页面层控制
            * ③、操作前校验(体验级)
            * ④、接口异常兜底(关键)
        • (7)、一个「简单但企业级」的典例
          • ①、后端规则(你要懂)
            * ②、前端权限上下文(示意)
            * ③、前端按钮控制
            * ④、操作前提示
            * ⑤、接口兜底处理
    • 3、动态菜单
      • (1)、动态菜单的概念
        • (2)、动态菜单在系统中的“正确位置”
        • (3)、为什么企业系统一定要用动态菜单?
        • (4)、动态菜单的三种主流设计模式(前端必须懂)
          • ①、后端全量下发菜单(最常见)
            * ②、前端根据权限过滤菜单(次常见)
            * ③、混合模式(企业级常见)
        • (5)、动态菜单的“标准数据模型”
        • (6)、前端做动态菜单的“标准步骤”
          • ①、登录后初始化权限上下文
            * ②、根据权限生成菜单树
            * ③、渲染菜单(UI 框架无关
            * ④、路由层兜底(非常关键)
        • (7)、一个「简单但企业级」的动态菜单典例
          • ①、后端返回数据(示意)
            * ②、前端生成菜单
            * ③、路由守卫兜底

一、概念

“用户权限与访问控制类业务”是指在用户身份已确认的前提下,通过角色、权限、规则和策略,决定用户:

  • 能不能访问
  • 能不能操作
  • 能看到什么

“用户权限与访问控制”在系统中的位置(非常重要):

1用户身份认证
2(你是谁)
3    
4用户权限与访问控制
5(你能不能)
6    
7业务功能执行
8

权限系统是身份认证与业务执行之间的“闸门”。

“用户权限与访问控制类业务”在前端主要体现为:

  • 登录态管理
  • 路由访问控制
  • 动态菜单
  • 操作级权限控制。

前端负责:权限的展示与引导

  • 前端权限系统的目标不是保证安全,而是降低误操作、减少越权尝试、提升用户体验。

后端负责:权限的裁决与执行

  • 真正的安全控制必须由后端统一裁决,前后端形成权限的双层校验体系。

二、权限与访问控制的「能力全景图」

从前端视角,把这个业务域拆成 8 大核心能力:

能力解决的问题前端是否参与
身份状态管理是否登录
角色模型用户是什么身份
权限点模型能做哪些操作
路由访问控制能进哪些页面
动态菜单能看到哪些入口
按钮级权限能点哪些操作
黑白名单是否强制禁止/放行⚠️(展示)
接口级校验是否真正允许❌(后端)

📌 前端主要负责:入口、展示、引导、体验控制

三、前端视角的「权限控制分层模型」(核心)

前端权限不是一层,而是四层:

  • 登录态层
  • 路由层
  • 菜单层
  • 组件 / 操作层

1、登录态层(Authentication State)

前端职责:

  • 判断是否已登录
  • 维护 Token / Session
  • 处理登录失效

典型实现:

  • 路由守卫
  • 请求拦截器
  • Token 过期重定向

📌 这是所有权限的前提条件

2、路由层(Page Access Control)

问题:用户能否访问某个页面?

实现方式:

  • 路由 meta.permission
  • 登录后动态注册路由
  • 未授权跳转 403

📌 防止“手输 URL 访问”

3、菜单层(Navigation Control)

问题:用户能看到哪些功能入口?

实现方式:

  • 后端返回菜单树
  • 或前端根据权限过滤菜单
  • 菜单 ≠ 路由(重要)

📌 菜单是权限的 UI 映射

4、组件 / 操作层(Action Control)

问题:用户能不能执行具体操作?

实现方式:

  • v-if / 权限指令
  • hooks / 高阶组件
  • 操作前二次校验

📌 按钮权限永远不能当安全机制

四、前端权限系统的“典型数据流”

1登录成功
2
3获取用户信息(角色 / 权限 / 菜单 / 名单状态)
4
5初始化权限上下文(Store)
6
7动态生成路由
8
9渲染菜单
10
11控制组件 / 操作
12

📌 这是90% 企业级系统的真实流程

五、权限模型的三种常见设计(前端必须懂)

  • 基于角色的 RBAC
  • 基于权限点的 PBAC
  • 基于属性/规则的 ABAC

1、RBAC(基于角色)

1用户  角色  权限
2

前端特点:

  • 好理解
  • 菜单生成简单
  • 扩展性一般

2、PBAC(基于权限点)

1用户  权限点
2

前端特点:

  • 按钮级控制友好
  • 菜单/操作粒度细
  • 前端维护成本较高

3、ABAC(基于属性/规则)

1用户属性 + 资源属性 + 环境属性
2

前端特点:

  • 前端只做展示
  • 复杂规则交给后端
  • 常见于金融风控

📌 金融系统:RBAC + ABAC 混合

六、重点「权限与访问控制」业务剖析

1、用户鉴权

没有可靠的用户鉴权,后面的权限、菜单、风控全部没有意义。

用户鉴权是整个系统安全的第一道防线:

  • 前端负责凭证的安全存储、携带和失效处理。
  • 后端负责身份真实性校验和凭证签发。

在企业和金融系统中通常采用双 Token 机制以兼顾安全性和用户体验。

(1)、用户鉴权概念

用户鉴权,是用于确认“当前发起请求的主体是谁,并且是否真实可信”的过程。

关键词只有一个:

  • 你是谁

鉴权 ≠ 权限(必须先区分):

项目用户鉴权用户权限
核心问题你是谁你能做什么
是否必须❌(视业务)
是否安全核心⚠️
典型产物Token / Session菜单 / 按钮 / 规则

📌 鉴权是所有安全体系的地基

(2)、用户鉴权的「标准模型」(企业级通用)

抽象成 4 个核心步骤:

  • 身份声明(Credentials)
  • 身份验证(Verify)
  • 身份凭证发放(Token / Session)
  • 身份凭证校验(Request Auth)

各步骤的职责分工(前端视角):

阶段前端职责后端职责
登录收集凭证验证真实性
发证存储凭证生成 Token
使用携带 Token校验 Token
失效处理过期判定失效

📌 前端 不验证身份真实性,只负责携带与管理凭证

(3)、主流鉴权方案全景对比(你必须会)

方案是否企业常用特点
Cookie + Session简单、CSRF 风险
JWT(Bearer Token)无状态、最主流
OAuth2 / SSO企业/平台级
双 Token(Access + Refresh)金融级
证书 / Key⚠️系统对系统

(4)、JWT 鉴权机制(前端必须吃透)

①、JWT 本质
1JWT = Header + Payload + Signature
2
  • Payload:用户身份声明(userId / role / exp)
  • Signature:防篡改

📌 JWT ≠ 加密,只是签名

②、企业级 JWT 设计(重点)

❌ 错误做法

  • JWT 放 localStorage
  • 永久有效
  • 前端完全信任 JWT

✅ 正确做法(金融级)

  • Access Token:短期(5~30min)
  • Refresh Token:长期(7~30d)
  • Refresh Token 存 HttpOnly Cookie
  • Access Token 仅用于请求

(5)、前端如何“正确”做用户鉴权(分层讲)

①、登录阶段(Login)

前端:

  • 收集账号 / 密码 / 验证码
  • HTTPS 发送

后端:

  • 验证身份
  • 返回 Token
1{
2  "accessToken": "xxx",
3  "expiresIn": 1800,
4  "user": {
5    "id": 1,
6    "name": "Alice"
7  }
8}
9
②、凭证存储(非常关键)

企业级推荐方案:

凭证存储位置
Access Token内存 / Store
Refresh TokenHttpOnly Cookie

📌 防 XSS + 防 CSRF 的平衡方案

③、请求鉴权(Request Authentication)

前端统一拦截器:

1axios.interceptors.request.use(config => {
2  config.headers.Authorization = `Bearer ${accessToken}`
3  return config
4})
5
④、过期处理(企业级重点)
1接口返回 401
2
3使用 Refresh Token
4
5刷新 Access Token
6
7重放原请求
8

📌 用户无感刷新登录态

(6)、一个「简单但完整」的企业级典例

下面是一个典型后台管理系统的鉴权方案。

技术栈:
前端:React / Vue SPA
后端:REST API
鉴权:JWT + 双 Token
场景:金融后台

①、登录流程
1/login
2
3校验账号密码
4
5返回 accessToken
6
7refreshToken 写入 HttpOnly Cookie
8
②、前端核心代码(示意)

登录成功处理:

1store.setAccessToken(token)
2store.setUser(userInfo)
3

请求拦截器:

1axios.interceptors.response.use(
2  res => res,
3  async err => {
4    if (err.response.status === 401) {
5      await refreshToken()
6      return axios(err.config)
7    }
8    return Promise.reject(err)
9  }
10)
11

路由守卫(鉴权入口):

1if (!accessToken && to.path !== '/login') {
2  redirect('/login')
3}
4
③、后端核心原则(前端要懂)

所有接口校验 Token:

  • Token 校验独立于菜单 / 权限
  • Token 失效立即拒绝请求

📌 鉴权是“所有接口”的第一道门

2、黑白名单

黑白名单并不属于权限模型,而是一种高优先级的访问控制与风控机制。
在系统中,它通常位于身份认证和权限校验之后,
前端仅负责展示与引导,最终是否允许访问由后端统一裁决。

权限决定“正常能不能做”,黑白名单决定“特殊情况下能不能做”。

(1)、黑白名单概念

黑白名单是一种“强制访问控制与风控兜底机制”,
用于在身份与权限校验通过之后,对特定主体进行“额外禁止或额外放行”。

📌 核心关键词:
强制 / 兜底 / 高优先级

黑白名单解决的不是“权限问题”:

问题是否由黑白名单解决
你是谁
你有什么权限
是否强制禁止
是否特权放行
是否临时控制

📌 黑白名单永远高于角色、权限、菜单

(2)、黑白名单在系统中的“正确位置”

标准安全顺序(金融系统):

  • 身份认证(Authentication)
  • 权限校验(Authorization)
  • 黑白名单 / 风控校验(Access Control)
  • 业务执行

黑白名单不是前置认证,而是“最终闸门”

(3)、黑白名单的业务分类(前端必须理解)

①、按“对象”分类
对象示例
用户封禁账号、风控用户
角色禁止某类用户操作
IP风控 IP
设备异常设备
接口临时封禁能力

📌 前端通常只感知“用户级 / 功能级”

②、按“作用方式”分类

黑名单(Block):

  • 强制禁止
  • 无视权限
  • 常用于风控

白名单(Allow):

  • 强制放行
  • 可绕过部分限制
  • 常用于内部 / 灰度

(4)、前端在黑白名单中的真实职责(重点)

⚠️ 非常关键的一点:

  • 前端不是黑白名单的裁决者,只是“感知者”和“执行者(展示层)”。

前端能做什么?

能力是否允许
隐藏入口
禁用按钮
操作前提示
阻断请求⚠️(体验层)
决定是否安全

🚫 前端不能做什么?

  • 决定是否真正允许
  • 作为唯一拦截手段
  • 依赖本地逻辑保证安全

(5)、企业级黑白名单的“数据模型”(你要会看)

后端返回的典型结构:

1{
2  "userId": 1001,
3  "blacklist": {
4    "global": false,
5    "actions": ["withdraw", "transfer"],
6    "reason": "风控冻结"
7  },
8  "whitelist": {
9    "actions": ["internal-debug"]
10  }
11}
12

📌 特点:

  • 不是简单 true / false
  • 有作用范围
  • 有原因
  • 可动态调整

(6)、前端如何“正确”使用黑白名单(分层讲)

①、初始化阶段(登录后)
1登录成功
2
3获取用户画像(含名单状态)
4
5写入权限上下文(Store)
6
②、菜单 / 页面层控制
1if (blacklist.actions.includes('withdraw')) {
2  hideMenu('withdraw')
3}
4

📌 只做展示控制

③、操作前校验(体验级)
1function beforeAction(action) {
2  if (blacklist.actions.includes(action)) {
3    showToast('当前账号已被限制操作')
4    return false
5  }
6  return true
7}
8

📌 防止无意义请求 + 明确提示用户

④、接口异常兜底(关键)

即使前端没拦住:

1接口请求
2
3后端黑名单校验
4
5返回 403 / 451
6
7前端统一提示
8

📌 这是最终安全兜底

(7)、一个「简单但企业级」的典例

场景说明:金融后台系统
功能:提现
风控:部分用户被临时冻结提现

①、后端规则(你要懂)
1if (user in withdraw_blacklist) {
2  reject request
3}
4
②、前端权限上下文(示意)
1const authContext = {
2  permissions: ['withdraw'],
3  blacklist: ['withdraw']
4}
5
③、前端按钮控制
1<Button
2  disabled={blacklist.includes('withdraw')}
3  onClick={handleWithdraw}
4>
5  提现
6</Button>
7
④、操作前提示
1function handleWithdraw() {
2  if (blacklist.includes('withdraw')) {
3    alert('账号风控中,暂不可提现')
4    return
5  }
6  submitWithdraw()
7}
8
⑤、接口兜底处理
1axios.post('/withdraw').catch(err => {
2  if (err.status === 403) {
3    alert('操作被系统拦截')
4  }
5})
6

📌 前后端双层拦截

3、动态菜单

动态菜单本质上是权限与访问控制结果在前端导航层的映射,
它的目标是降低误操作风险、提升可用性与合规性,
但并不参与最终的安全裁决,真正的权限校验必须由后端完成。

动态菜单不是“你能不能做”,而是“你该不该看到”。

(1)、动态菜单的概念

动态菜单,是“用户权限与访问控制结果在前端的导航层映射”,用于决定“当前用户能看到哪些功能入口”。

📌 关键词:
权限结果 / 导航层 / 展示与引导

🚫 动态菜单不解决什么?

  • 不解决身份认证
  • 不解决真正的安全校验
  • 不防止接口越权

📌 它不是安全机制,而是“权限的 UI 表现”

(2)、动态菜单在系统中的“正确位置”

在企业 / 金融系统中,完整链路是:

1身份认证(你是谁)
2
3权限 / 黑白名单(你能不能)
4
5动态菜单(你能看到什么)
6
7路由访问
8
9具体操作
10

菜单一定发生在“权限已确定之后”

(3)、为什么企业系统一定要用动态菜单?

业务复杂度决定的:

  • 不同角色看到完全不同系统
  • 功能频繁开关 / 灰度
  • 多租户 / 多业务线

📌 静态菜单根本不可维护

金融系统的现实需求:

  • 降低误操作风险
  • 减少越权尝试
  • 强化合规性(“你不该看到的就不要看到”)

(4)、动态菜单的三种主流设计模式(前端必须懂)

①、后端全量下发菜单(最常见)
1后端根据权限
2
3直接返回可用菜单树
4
5前端直接渲染
6

特点:

  • 前端最简单
  • 权限集中在后端
  • 金融系统最常用

📌 推荐指数:⭐⭐⭐⭐⭐

②、前端根据权限过滤菜单(次常见)
1后端返回权限点
2
3前端本地菜单表
4
5根据权限过滤
6

特点:

  • 前端更灵活
  • 维护成本高
  • 易出错

📌 适合中后台、内部系统

③、混合模式(企业级常见)
1后端返回菜单骨架 + 权限
2
3前端补充结构 / 本地能力
4

📌 大型系统 / 微前端常用

(5)、动态菜单的“标准数据模型”

企业级菜单一定是树结构 + 元数据:

1[
2  {
3    "key": "fund",
4    "title": "资金管理",
5    "icon": "money",
6    "path": "/fund",
7    "children": [
8      {
9        "key": "withdraw",
10        "title": "提现",
11        "path": "/fund/withdraw",
12        "permission": "withdraw"
13      }
14    ]
15  }
16]
17

核心字段说明:

字段作用
key唯一标识
title菜单名
path路由路径
permission所需权限
children子菜单

📌 菜单 ≠ 路由,但通常一一对应

(6)、前端做动态菜单的“标准步骤”

①、登录后初始化权限上下文
1登录成功
2
3获取用户信息(角色 / 权限 / 菜单)
4
5存入 Store
6
②、根据权限生成菜单树
1function filterMenu(menu, permissions) {
2  return menu
3    .filter(item =>
4      !item.permission || permissions.includes(item.permission)
5    )
6    .map(item => ({
7      ...item,
8      children: item.children
9        ? filterMenu(item.children, permissions)
10        : []
11    }))
12}
13

📌 纯函数、可测试

③、渲染菜单(UI 框架无关
1<Menu>
2  {menu.map(item => (
3    <MenuItem key={item.key} to={item.path}>
4      {item.title}
5    </MenuItem>
6  ))}
7</Menu>
8
④、路由层兜底(非常关键)

即使菜单隐藏了:

1用户手输 URL
2
3路由守卫校验权限
4
5无权限  403
6

📌 菜单永远不能当路由安全

(7)、一个「简单但企业级」的动态菜单典例

场景说明:金融后台
角色:普通用户 / 管理员
功能:查看账户 / 提现 / 审批

①、后端返回数据(示意)
1{
2  "permissions": ["view", "withdraw"],
3  "menu": [
4    {
5      "key": "account",
6      "title": "账户",
7      "path": "/account"
8    },
9    {
10      "key": "withdraw",
11      "title": "提现",
12      "path": "/withdraw",
13      "permission": "withdraw"
14    },
15    {
16      "key": "approve",
17      "title": "审批",
18      "path": "/approve",
19      "permission": "approve"
20    }
21  ]
22}
23
②、前端生成菜单
1const menu = filterMenu(menuFromServer, permissions)
2

结果只剩:

  • 账户
  • 提现
③、路由守卫兜底
1if (!hasPermission(route.permission)) {
2  redirect('/403')
3}
4

📌 企业级必备


权限与访问控制》 是转载文章,点击查看原文


相关推荐


智谱年末王炸:GLM-4.7开源,这可能是给程序员最好的圣诞礼物
墨风如雪2025/12/23

2025年的年底,本以为AI圈的大战会随着节日季的到来暂时偃旗息鼓,没想到智谱AI在这个节点扔下了一枚重磅炸弹。 就在12月23日,他们正式发布并开源了GLM-4.7。这不仅仅是一次常规的版本号迭代,更像是一次针对开发者痛点的精准爆破。如果你还在为开源模型写不出能跑的代码而头疼,或者还在心疼闭源API高昂的账单,那么GLM-4.7可能正是你在等的那个破局者。 这不是参数堆砌,是实打实的“智力”升级 先说最直观的感受。过去我们用开源模型写代码,往往是“一看顿悟,一跑报错”。但这次GLM-4.7在


【鸿蒙开发案例篇】鸿蒙6.0的pdfService与pdfViewManager终极爆破
威哥爱编程2025/12/15

大家好,我是V哥。 兄弟们抄家伙!今天给大家分享用鸿蒙6.0的PDF Kit撕碎文档开发防线,全程高能代码扫射,专治各种PDF开发不服!以下基于HarmonyOS 6.0(API 21)的ArkTS实战,弹药已上膛👇 联系V哥获取 鸿蒙学习资料 💣 第一弹:pdfService——文档底层爆破术 核心能力:文档加载/编辑/转换 import { pdfService } from '@kit.PDFKit'; import { BusinessError } from '@kit.Ba


手写 EventEmitter:深入理解发布订阅模式
1024肥宅2025/12/7

引言 在 JavaScript 开发中,事件驱动编程是构建可维护、可扩展应用的核心范式之一。从浏览器 DOM 事件到 Node.js 的异步 I/O,从 Vue 的组件通信到 React 的状态管理,发布订阅模式无处不在。 通过手写一个符合 Node.js EventEmitter 标准的实现,我们不仅能深入理解事件驱动架构的设计原理,还能掌握 JavaScript 中闭包、内存管理、设计模式等核心概念。更重要的是,这是面试中常见的高级题目,能体现你对JavaScript设计模式的理解深度。 本


C#小案例-->让两个线程交替打印偶数和奇数值(并发)
MM_MS2025/11/28

方法一: 编写代码实现切换逻辑 using System; using System.Threading; namespace 让两个线程交替打印偶数和奇数值_并发_ { internal class Program { // ===================== 共享资源与同步工具 ===================== // 1. 偶数线程的当前值(初始为0,每次+2,打印偶数) private static i


后端线上发布计划模板
uzong2026/1/10

敬畏每一行代码,敬畏每一次变更。 本模板旨在通过结构化、可验证、可回溯的方式,降低发布风险,保障系统稳定。 一、📅 发布基本信息 项目内容发布名称示例:用户中心 v2.3.0 上线发布时间2026-01-15 01:00 – 02:30发布负责人xxx协同人员xxx发布类型✅ 功能上线 / 🔁 配置变更 / 🐞 紧急修复 / ⚙️ 架构调整是否灰度发布是 / 否(若“是”,说明策略:如 5% → 20% → 100%) 二、


2026前端面试题及答案
阿芯爱编程2026/1/18

2026前端面试题及答案 HTML/CSS 部分 1. 什么是盒模型?标准盒模型和IE盒模型的区别是什么? 答案: 盒模型是CSS中用于布局的基本概念,每个元素都被表示为一个矩形盒子,由内容(content)、内边距(padding)、边框(border)和外边距(margin)组成。 区别: 标准盒模型(W3C盒子模型):width和height只包含内容(content) IE盒模型(怪异模式盒子模型):width和height包含内容(content)、内边距(padding)和边框(b

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客