You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
这段代码是不 work 的,因为当前权限信息是通过接口异步获取的,此时Authorized组件获取不到当前权限(currentAuthority),倘若直接通过 url 访问/user-page或/admin-page,不论用户身份是否符合,请求结果未回来,都会被重定向到/login或/403,这个问题后面再谈。
前端进行权限控制只是为了用户体验,对应的角色渲染对应的视图,真正的安全保障在后端。
前言
毕业之初,工作的主要内容便是开发一个后台管理系统,当时存在的一个现象是:
用户若记住了某个 url,直接浏览器输入,不论该用户是否拥有访问该页面的权限,均能进入页面。
若页面初始化时(
componentDidMount
)进行接口请求,后端会返回 403 的 HTTP 状态码,同时前端封装的request.js
会对非业务异常进行相关处理,遇见 403,就重定向到无权限页面。若是页面初始化时不存在前后端交互,那就要等用户触发某些操作(比如表单提交)后才会触发上述流程。
可以看到,安全保障是后端兜底的,那前端能做些什么呢?
最近也在看
Ant Design Pro
的权限相关处理,有必要进行一次总结。需要注意的是,本文虽然基于
Ant Design Pro
的权限设计思路,但并不是完全对其源码的解读(可能更偏向于 v1 的涉及思路,不涉及 umi)。如果有错误以及理解偏差请轻捶并指正,谢谢。
模块级别的权限处理
假设存在以下关系:
某页面上存在一个文案为“进入管理后台”的按钮,只对管理员展示,让我们实现一下。
简单实现
好吧,简单至极。
权限控制就是
if else
,实现功能并不复杂,大不了每个页面|模块|按钮涉及到的处理都写一遍判断就是了,总能实现需求的。不过,现在只是一个页面中的一个按钮而已,我们还会碰到许多“某(几)个页面存在某个 xxx,只对 xxx(或/以及 xxx) 展示”的场景。
所以,还能做的更好一些。
下面来封装一个最基本的权限管理组件
Authorized
。组件封装-Authorized
期望调用形式如下:
api 如下:
currentAuthority
这个属性没有必要每次调用都手动传递一遍,此处假设用户信息是通过redux
获取并存放在全局store
中。注意:我们当然也可以将用户信息挂在
window
下或者localStorage
中,但很重要的一点是,绝大部分场景我们都是通过接口异步获取的数据,这点至关重要。如果是html
托管在后端或是ssr
的情况下,服务端直接注入了用户信息,那真是再好不过了。新建
src/components/Authorized/Authorized.jsx
实现如下:现在我们无需手动传递
currentAuthority
:✨ 很好,我们现在迈出了第一步。
页面级别的权限处理
页面就是放在
Route
组件下的模块。知道这一点后,我们很轻松的可以写出如下代码:
新建
src/router/index.jsx
,当用户角色与路由不匹配时,渲染Redirect
组件用于重定向。这段代码是不 work 的,因为当前权限信息是通过接口异步获取的,此时
Authorized
组件获取不到当前权限(currentAuthority
),倘若直接通过 url 访问/user-page
或/admin-page
,不论用户身份是否符合,请求结果未回来,都会被重定向到/login
或/403
,这个问题后面再谈。先优化一下我们的代码。
抽离路由配置
路由配置相关 jsx 内容太多了,页面数量过多就不好维护了,可读性也大大降低,我们可以将路由配置抽离出来。
新建
src/router/router.config.js
,专门用于存放路由相关配置信息。组件封装-AuthorizedRoute
接下来基于
Authorized
组件对Route
组件进行二次封装。新建
src/components/Authorized/AuthorizedRoute.jsx
。实现如下:
优化后
现在重写我们的 Router 组件。
心情舒畅了许多。
可是还留着一个问题呢——由于用户权限信息是异步获取的,在权限信息数据返回之前,
AuthorizedRoute
组件就将用户推到了redirectPath
。异步获取权限
解决思路很简单:保证相关权限组件挂载时,redux 中已经存在用户权限信息。换句话说,接口数据返回后,再进行相关渲染。
我们可以在 Layout 中进行用户信息的获取,数据获取完毕后渲染
children
。The text was updated successfully, but these errors were encountered: