← 返回题目列表

前端权限控制能保证安全吗?路由守卫和按钮权限应该怎么做?

高频 中等 第 5 / 26 题 更新于 2026/07/29
权限控制路由守卫RBAC前端安全

简化版

前端权限控制只能改善体验和减少误操作,不能作为真正安全边界。路由守卫、菜单权限、按钮权限都可能被用户绕过;关键接口必须由服务端基于用户身份和权限重新校验。

详细版

前端常做三层权限:菜单是否展示、路由是否可进入、按钮或操作是否可点击。它们应来自服务端下发的权限数据,并在前端做缓存和渲染控制。

router.beforeEach((to, from, next) => {
  if (!auth.isLogin()) return next('/login')
  if (to.meta.permission && !auth.has(to.meta.permission)) return next('/403')
  next()
})

但用户可以直接改前端状态、调用接口、构造请求或绕过按钮。因此所有写操作、敏感查询、导出、审批、管理接口都必须在后端鉴权。面试中要把前端权限定位为“体验层控制”,后端权限定位为“安全层控制”。

完整版教学

一、为什么前端权限不是安全边界

前端代码运行在用户浏览器里,用户能看到代码、修改内存、调用接口、伪造请求。隐藏按钮只能阻止普通用户误点,不能阻止攻击者在控制台里调用接口。

// 控制台里可以直接尝试请求
fetch('/api/admin/users', { credentials: 'include' })

记忆钩子:前端管“看不看得到”,后端管“能不能真的做”。

二、前端权限控制的三层

层级作用安全边界
菜单权限不展示无权限入口不是
路由守卫进入页面前拦截不是
按钮权限隐藏或禁用操作按钮不是
接口鉴权服务端校验身份和权限

这几层都要做,但目的不同。前端层让产品体验清晰,后端层保证攻击者不能越权。只做后端不做前端,用户体验差;只做前端不做后端,系统不安全。

三、路由守卫怎么设计

const routes = [
  { path: '/users', component: Users, meta: { permission: 'user:list' } },
  { path: '/admin', component: Admin, meta: { permission: 'admin:entry' } },
]

router.beforeEach(async (to, from, next) => {
  if (!auth.token) return next('/login')
  if (!auth.permissionsLoaded) await auth.loadPermissions()
  if (to.meta.permission && !auth.has(to.meta.permission)) return next('/403')
  next()
})

守卫要处理刷新后权限未加载的情况。很多 bug 出在首屏刷新:内存里的权限丢了,路由先判断失败,导致用户被错误踢到 403。通常要先恢复登录态、拉取用户信息和权限,再做路由判断。

四、按钮权限和操作权限

function can(permission) {
  return userPermissions.has(permission)
}

// 模板中只展示有权限的按钮
// v-if="can('user:delete')"

按钮权限适合控制删除、导出、审批、配置等敏感操作的入口。但按钮隐藏不等于接口安全,攻击者可以直接调用 /api/user/delete。后端必须根据当前用户、资源归属、角色和数据范围再次判断。

一个常见数字例子:页面隐藏了 1 个“删除用户”按钮,但接口没有鉴权;攻击者只要知道 1 个接口路径,就可能删除 1000 条数据。前端少显示 1 个按钮,挡不住直接请求。

五、RBAC、ABAC 与数据权限

模型判断依据例子
RBAC用户拥有哪些角色管理员、运营、访客
Permission用户拥有哪些动作权限user:createorder:export
ABAC属性和上下文部门、地区、时间、资源归属
数据权限能看哪些数据范围只能看本部门订单

前端常拿到的是菜单树和动作权限码,但真正复杂的是数据权限。用户能进入订单页,不代表能看所有订单;服务端查询时必须加租户、组织、资源归属等条件。

六、接口鉴权要覆盖什么

请求 -> 身份认证 -> 权限校验 -> 数据范围校验 -> 审计日志 -> 执行业务

后端不能只判断“是否登录”。还要判断用户是否有该动作权限、是否能操作该资源、是否跨租户、是否超过数据范围。前端传来的 role=adminuserId=123tenantId=1 都不能直接信任。

对于导出、批量删除、审批通过这类高风险操作,后端还应记录审计日志,必要时增加二次确认或风控。

七、常见误区与追问

  • 误区:隐藏按钮就完成权限控制。 用户可以直接构造请求,按钮权限只是体验控制。
  • 误区:路由守卫可以保护接口。 守卫只在前端运行,接口必须服务端鉴权。
  • 误区:JWT 里有角色就完全可信。 后端要验证签名、有效期、撤销状态和最新权限。
  • 追问:刷新后权限丢失怎么办? 先恢复身份并拉取权限,再执行路由判断。
  • 追问:菜单权限和数据权限有什么区别? 菜单控制入口,数据权限控制能看或操作哪些资源。
  • 追问:前端传 isAdmin=true 能信吗? 不能,权限必须以后端可信身份和服务端数据为准。

八、加强记忆

前端权限控制要用“两层边界”记:前端边界是体验边界,负责菜单、路由、按钮;后端边界是安全边界,负责认证、动作权限、资源归属和数据范围。面试回答不能把前端守卫说成安全方案,必须明确所有敏感接口都要在服务端重新校验。