背景 :npm i @ant-design/pro-cli -g pro create myapp 生成框架 , 当我们不登录,直接进入其他页面,它就会退出去登录页面,那么它是如何做的呢? 又或者说,它的权限控制是如何做的?
-----------------------------------------------
在分析之前,我只想说,这个框架就是 bolt shit,完全是因为同事有人在项目中使用了这个框架去做项目的初始化。 重得不行,封装得跟个黑盒一样。
用Umi官网的生成简单框架就够了,请求,路由,layout自己配,根据项目的复杂度再渐进式的去增加功能。
-----------------------------------------------
问题: antd pro 框架 为什么能帮我在未登录的情况下帮我重定向到登录页?
框架的权限控制的使用
四个方面 , 具体可以看 https://umijs.org/docs/max/access
一、在config.ts配置
export default {
access: {},
// access 插件依赖 initial State 所以需要同时开启
initialState: {},
};
二、在routers中配置
重点: access: 'canAdmin', ---- 这里代表,访问它需要有这个字段 (这里有个问题,框架底层它拿这个字段去哪里对比呢?看第三步)
{
path: '/admin',
name: 'admin',
icon: 'crown',
access: 'canAdmin', ---- 这里,这里代表,访问它需要有这个字段 (这里有个问题,框架底层它拿这个字段去哪里对比呢?看第三步)
routes: [
{
path: '/admin',
redirect: '/admin/sub-page',
},
{
path: '/admin/sub-page',
name: 'sub-page',
component: './Admin',
},
],
},
三、src/access.ts的文件 ,它会在每次切换路由的时候被调用 (又或许是路由配置access字段时被调用)
export default function access(initialState: { currentUser?: API.CurrentUser } | undefined) {
const { currentUser } = initialState ?? {};
return {
canAdmin: currentUser && currentUser.access === 'admin', ----- 这里就可以看到,它是拿这个字段值,跟routes access字段对比
};
}
四、在app.ts 定义初始化的 access函数的 initialState
重点: 这里return值就是 initialState
if (location.pathname !== loginPath) {
const currentUser = await fetchUserInfo();
return {
fetchUserInfo,
currentUser,
export async function getInitialState(): Promise<{
settings?: Partial<LayoutSettings>;
currentUser?: API.CurrentUser;
loading?: boolean;
fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
}> {
const fetchUserInfo = async () => {
try {
const msg = await queryCurrentUser({
skipErrorHandler: true,
});
return msg.data;
} catch (error) {
history.push(loginPath);
}
return undefined;
};
// 如果不是登录页面,执行
const { location } = history;
if (location.pathname !== loginPath) {
const currentUser = await fetchUserInfo();
return {
fetchUserInfo,
currentUser,
settings: defaultSettings as Partial<LayoutSettings>,
};
}
return {
fetchUserInfo,
settings: defaultSettings as Partial<LayoutSettings>,
};
}
总结: 当在routes对某个路由配置 access字段时,就要对两个位置进行配置(config只要配置一次就不算了) 分别是 access.ts文件,app的getInitState钩子函数。
那么,当没权限时,它是在哪里帮你跳转回登录页面呢?
重点: 还是在 app.ts文件下配置 ,有个layout的钩子函数,
export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
return {
....
onPageChange: () => {
const { location } = history;
// 如果没有登录,重定向到 login
if (!initialState?.currentUser && location.pathname !== loginPath) {
history.push(loginPath);
}
},
...
参考: 权限