Frontend Development 9 min read

Frontend SDK Design and Integration for a Unified Permission System

This article explains how to design a unified permission system's frontend SDK, detailing its core APIs, integration methods for standard React and Umi projects, dynamic route generation, and menu/button level permission controls, accompanied by practical code examples.

Zhuanzhuan Tech
Zhuanzhuan Tech
Zhuanzhuan Tech
Frontend SDK Design and Integration for a Unified Permission System

Building on previous design and backend implementation articles, this final piece introduces the frontend SDK for a unified permission system, which provides login , getUserPermssion , and a special routerFilter API to fetch user data and filter menu trees.

For ordinary React projects, the SDK is invoked before the app mounts using commonLogin to obtain userInfo and permissionInfo , after which routerFilter can be applied to the route configuration:

import { commonLogin } from '@zz-common/zz-permission';
(async () => {
  const { userInfo = {}, permissionInfo = {} } = await commonLogin({ appCode: '' });
  const { resources } = permissionInfo;
  render();
})();
import { routerFilter } from '@zz-common/zz-permission';
const router = [];
const newRouter = routerFilter(router);

For Umi projects, install the access plugin, then modify src/app.ts to call commonLogin and store the permission list in initialState :

// app.ts
import { commonLogin } from '@zz-common/zz-permission';
export async function getInitialState() {
  const { permissionInfo, userInfo } = await commonLogin({ appCode: '' });
  const { resources = [] } = permissionInfo;
  return { userInfo, permissionList: resources };
}

Create src/access.ts to map route access fields to permission codes, generating an accessList object used by Umi's Access component.

import routes from '../config/routes';
function findRouteAccessList() { /* ... */ }
export default (initialState = {}) => {
  const { permissionList = [] } = initialState;
  const accessList = permissionList.reduce((acc, item) => { acc[item.code] = true; return acc; }, {});
  const routePermissions = findRouteAccessList();
  routePermissions.forEach(key => { if (!(key in accessList)) accessList[key] = false; });
  return accessList;
};

A CheckAuth component wraps buttons to hide them when the corresponding permission code is false:

import React from 'react';
import { useAccess, Access } from 'umi';
const CheckAuth = ({ children, permissionCode }) => {
  const access = useAccess();
  const accessible = access[permissionCode];
  return
{children}
;
};
export default CheckAuth;

Dynamic permission‑based menus are achieved by fetching a permission tree from the backend and merging it with local routes. Helper functions in dynamicRoute.ts (e.g., renderRoutes , getRedirectRoute ) flatten local routes, render components, and build a combined route list.

export function renderRoutes(sourceRoutes = [], localRoutes = []) { /* ... */ }
export function getRedirectRoute(routes = [], cataloguePath = '/') { /* ... */ }

The patchRoutes runtime hook replaces the original route configuration with the generated routes, adds a redirect route, and appends a 404 fallback.

export function patchRoutes({ routes }) {
  const localRoutes = routes[0].routes[0].routes;
  const mainRoutes = renderRoutes(authRoutes, localRoutes);
  const redirectRoute = getRedirectRoute(mainRoutes);
  if (redirectRoute) mainRoutes.unshift(redirectRoute);
  mainRoutes.push({ component: NotFound });
  routes[0].routes[0].routes = mainRoutes;
}

In summary, the SDK centralizes permission handling for menus, routes, and button visibility; it must be invoked before rendering, and when combined with the company’s Umi scaffolding, it enables a streamlined, permission‑aware front‑end architecture.

frontendSDKreactpermissionUmiDynamic Routingaccess-control
Zhuanzhuan Tech
Written by

Zhuanzhuan Tech

A platform for Zhuanzhuan R&D and industry peers to learn and exchange technology, regularly sharing frontline experience and cutting‑edge topics. We welcome practical discussions and sharing; contact waterystone with any questions.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.