https://pro.ant.design/docs/authority-management-cn
ant-design-pro 1.0.0 V4
最近需要项目需要用扫码登录,因此就使用antd pro提供的鉴权能力来做
Authorized.ts
提供初始化路由组件和重载路由的函数
import RenderAuthorize from '@/components/Authorized';
import { getAuthority } from './authority';
/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable import/no-mutable-exports */
let Authorized = RenderAuthorize(getAuthority());
// Reload the rights component
const reloadAuthorized = (): void => {
Authorized = RenderAuthorize(getAuthority());
};
export { reloadAuthorized };
export default Authorized;
这里调用 RenderAuthorize(getAuthority()),如果我当前localStorage存的是antd-pro-authority:["admin"] ,则调用实际是 RenderAuthorize(["admin"]) ,直接导至执行以下函数,返回权限组件components/Authorized/Authorized,其中 CURRENT 返回的是当前权限,也即 ["admin"]
currentAuthority => {
if (currentAuthority) {
if (typeof currentAuthority === 'function') {
CURRENT = currentAuthority();
}
if (
Object.prototype.toString.call(currentAuthority) === '[object String]' ||
Array.isArray(currentAuthority)
) {
CURRENT = currentAuthority;
}
} else {
CURRENT = 'NULL';
}
return Authorized;
};
完整如下:renderAuthorize.js
/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable import/no-mutable-exports */
let CURRENT = 'NULL';
/**
* use authority or getAuthority
* @param {string|()=>String} currentAuthority
*/
const renderAuthorize = Authorized => currentAuthority => {
if (currentAuthority) {
if (typeof currentAuthority === 'function') {
CURRENT = currentAuthority();
}
if (
Object.prototype.toString.call(currentAuthority) === '[object String]' ||
Array.isArray(currentAuthority)
) {
CURRENT = currentAuthority;
}
} else {
CURRENT = 'NULL';
}
return Authorized;
};
export { CURRENT };
export default Authorized => renderAuthorize(Authorized);
值得注意的是,Authorized是在中间被注入的,components/Authorized/index
import Authorized from './Authorized';
import Secured from './Secured';
import check from './CheckPermissions';
import renderAuthorize from './renderAuthorize';
Authorized.Secured = Secured;
Authorized.check = check;
const RenderAuthorize = renderAuthorize(Authorized);
export default RenderAuthorize;
此时问题聚焦到:components/Authorized/Authorized
import React from 'react';
import check from './CheckPermissions';
const Authorized = ({ children, authority, noMatch = null }) => {
const childrenRender = typeof children === 'undefined' ? null : children;
const dom = check(authority, childrenRender, noMatch);
return <>{dom}</>;
};
export default Authorized;
这里使用CheckPermissions对权限作判断,里面实现了对权限的判断逻辑,以及在页面未加载完毕时,控制显示loading的图标
最后回到pages/Authorized上
return (
<Authorized
authority={getRouteAuthority(location.pathname, routes) || ''}
noMatch={isLogin ? <Redirect to="/exception/403" /> : <Redirect to="/user/login" />}
>
{children}
</Authorized>
);
修改后
<Authorized
authority={getRouteAuthority(location.pathname, routes) || ''}
// noMatch={isLogin ? <Redirect to="/exception/403" /> : <Redirect to={`/login?${getPageQuery()}`} />}
currentAuthority={currentAuthority}
noMatch={<Redirect to="/exception/403" />}
>
{children}
</Authorized>
authority传入的是我们在config中路由配置里预定义的权限,noMatch传入的是当鉴权不通过时,应该怎么做,这里加了判断登录,若权限不通过,未登录的立即跳登录,否则即显示权限禁止页,这是适用菜单切换的鉴权,不过,调用登录接口,执行登录逻辑不适合在此做。因为,在layouts/SecurityLayout做登录逻辑更适合,它也是先于其他组件加载的。
我的做法是,让pages/Authorized只判断权限跳403,登录的鉴权交给layouts/SecurityLayout做,这时还不够,还需要修改check的CURRENT的值为在pages/Authorized传入,因为我发现,鉴权组件一开始就会被加载,因此被注入的权限CURRENT不是最新的,所以现在改为实时传入
2020年3月26日:该文章部分内容已过时,请关注 官方发布