利用umi插件快速实现权限控制

简介: 本文介绍在umijs3中如何利用内置插件快速集成权限管理功能。

umi3内置了@umijs/plugin-access可以快速实现精细的权限控制功能,本文将会实现页面级的权限功能,并给出实现代码。

本文使用的的umi版本为3.x。

关于 @umijs/plugin-access

src/access.ts 时启用。

我们约定了 src/access.ts 为我们的权限定义文件,该文件需要默认导出一个方法,导出的方法会在项目初始化时被执行。该方法需要返回一个对象,对象的每一个值就对应定义了一条权限。

按照文档,我们将实现一个可读权限,没有权限时显示404页面。

// src/access.ts
export default function (initialState) {
  const { userInfo } = initialState;

  return {
   read: userInfo.userName === 'abc',
  };
}

关于 @umijs/plugin-initial-state

上面代码中的initialState来源于另一个插件@umijs/plugin-initial-state:

src/app.ts 并且导出 getInitialState 方法时启用。

按文档说明,添加如下配置:

export function getInitialState() {
  return new Promise((resolve) => {
    // 模拟 api请求获取用户信息
    setTimeout(
    () => {
        resolve({
        userInfo: { userName: 'abc' },
      });
    }, 500);
   });
}

正常情况下,应该可以在src/.umi目录下看到生成的plugin-initial-stateplugin-access目录,表示我们成功启用了这两个插件。

代码中使用

全局设置

一般umi项目中会有一个全局的布局文件 src/layouts/index.ts,里面组件的props.children为当前路由需要渲染的页面,我们可以在这里对权限进行判断,没有权限时显示404页面:

import NotFound from '@/pages/404';
import { useAccess } from 'umi';

const { children } = props;
const access = useAccess();
const authChildren = access.read ? children : <NotFound />;
 

把要渲染的组件换成authChildren即可。

其他页面设置

@umijs/plugin-access还提供了Access组件:

import { useAccess, Access } from 'umi';
import NotFound from '@/pages/404';

const EditPage = props => {

  const access = useAccess(); 
 
  return (
    <div>
      <Access
        accessible={access.write}
        fallback={<NotFound />}
      >
        Edit page
      </Access>
    </div>
  );
};

其他

这部分主要讲讲实践中遇到的问题以及解决方法。

与dva状态同步

我们一般会把用户信息存放在dva model中,如果我们在getInitialState中调用了获取了用户信息的方法,我们可以同步到dva model中,省去了在dva中触发effect再调用一次相同的接口:

// src/access.ts
import { getDvaApp } from 'umi';

export default function (initialState) {
  const { userInfo } = initialState;

  // 触发reducer
  getDvaApp()._store.dispatch({ type: 'common/update', userInfo });
  
  return {
   read: userInfo.userName === 'abc',
  };
}

如何动态修改access中的值?

翻一下插件生成的代码找找思路:

// src/.umi/plugin-access/AccessProvider.ts
  const { initialState } = useModel('@@initialState');

  const access: AccessInstance = useMemo(() => accessFactory(initialState as any), [initialState]);

  return React.createElement(
    AccessContext.Provider,
    { value: access },
    React.cloneElement(children, {
      ...children.props,
      routes:traverseModifyRoutes(props.routes, access)
    }),
  );

可以看到,只是在根元素外面套了一层context,而我们要动态修改的,是这个access的值。它在一个useMemo中返回, 因此我们要修改access,只需修改initalState即可。

而修改initalState的方法很简单:

import { useModel } from 'umi';

const { initialState, setInitialState } = useModel('@@initialState');

setInitialState({ ...initialState, userInfo: { userName: 'newUser' } });

即可触发access的修改, 重新执行src/access.ts中的逻辑。

目录
相关文章
|
测试技术 Windows
umi如何配置环境变量
umi如何配置环境变量
793 0
|
前端开发 JavaScript API
020 Umi@4 中如何实现动态菜单
020 Umi@4 中如何实现动态菜单
1251 0
020 Umi@4 中如何实现动态菜单
|
存储 缓存 前端开发
Antd Upload + React-Cropper 实现图片自定义区域剪裁并上传功能
通过Upload组件结合react-Cropper实现图片的裁剪上传组件封装,剖析antd-img-crop源码实现的逻辑,对自己封装的组件进行进一步优化,改造!
5303 0
Antd Upload + React-Cropper 实现图片自定义区域剪裁并上传功能
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
639 1
|
缓存 前端开发 JavaScript
浅浅阅读umi中InitialState插件源码 - 杨磊
InitialState插件源码的简要介绍
1232 0
浅浅阅读umi中InitialState插件源码 - 杨磊
|
iOS开发 MacOS Windows
electron-updater实现electron全量版本更新
electron-updater实现electron全量版本更新
1937 9
electron-updater实现electron全量版本更新
|
缓存 JavaScript 安全
【Ant Design Pro】使用ant design pro做为你的开发模板(四) 联调正式后台接口与运行时全局配置
【Ant Design Pro】使用ant design pro做为你的开发模板(四) 联调正式后台接口与运行时全局配置
1894 0
【Ant Design Pro】使用ant design pro做为你的开发模板(四) 联调正式后台接口与运行时全局配置
|
网络协议 算法 数据安全/隐私保护
HTTP2和HTTP3区别?HTTP2有什么缺点?
总的来说,如果把HTTP/2比作是优化过的汽车,那HTTP/3就像是直升飞机,它不仅飞得快,而且即使前面有障碍也不会轻易停下。想要网站速度更快,HTTP/3无疑提供了更好的选择。
915 3
|
前端开发 搜索推荐 数据可视化
阿里低代码引擎LowCodeEngine正式开源
低代码引擎是一款为低代码平台开发者提供的,具备强大扩展能力的低代码研发框架。由阿里巴巴前端委员会、钉钉宜搭联合出品。使用者只需要基于低代码引擎便可以快速定制符合自己业务需求的低代码平台。
阿里低代码引擎LowCodeEngine正式开源
|
JavaScript
成功解决node、node-sass和sass-loader版本冲突问题、不需要降低node版本。如何在vue项目中安装node-sass,以及安装node-sass可能遇到的版本冲突问题
这篇文章介绍了在Vue项目中安装node-sass和sass-loader时遇到的版本冲突问题,并提供了解决这些问题的方法,包括在不降低node版本的情况下成功安装node-sass。
成功解决node、node-sass和sass-loader版本冲突问题、不需要降低node版本。如何在vue项目中安装node-sass,以及安装node-sass可能遇到的版本冲突问题