我目前正在开发一个具有 RBAC 的应用程序,因此不同的用户将根据他们的角色看到更多的元素。
我使用 JWT 保护应用程序,必须在登录时检索该应用程序,然后在每个 API 调用中传递并存储在 localStorage 中。
我的问题是,如果有人更改状态并将我的状态变量设置为已登录且某个用户,他们将能够看到管理员可以做什么,他们可能无法使用后端命令,但他们可以获得查看可能性以及与之相关的端点。
我想知道是否可以使用 Webpack 来分离捆绑包,以便我们可以首先验证用户是否属于正确的类型,然后向他们提供一个 SPA,其中仅包含用户可能的选项?有点像服务器端渲染页面,删除了所有其他角色,并保留了其角色的所有功能。
为了基于相同的源代码创建多组捆绑包,您可以从您导出配置数组
webpack.config.js
(docs)。
在每个配置中,您可以使用 DefinePlugin 自由定义一些必要的标志:
module.exports = [
{
//...
// admin config
//...
plugins: [
new webpack.DefinePlugin({
ROLE: 'admin'
})
]
},
{
//...
// user config
//...
plugins: [
new webpack.DefinePlugin({
ROLE: 'user'
})
]
}
]
然后在源代码中您可以使用
process.env.ROLE
来启用/禁用某些功能:
if (process.env.ROLE === 'admin') { /* show red alert button */}
最终,死代码消除将为您删除这些部分。因此,您将拥有包含不同功能的多个捆绑包。
无需拥有整个单独的捆绑包即可实现此目的的另一种方法是为包含管理部分的单独块并延迟加载它们。
使用 webpack 5,您需要将其配置为为您的块生成动态导入,以便它们可以仅为有权查看它们的用户进行延迟加载。
AdminLazyHelper.js
import {lazy} from "react";
export let AdminPanelLazy =
lazy(() => import(/* webpackChunkName: 'admin/AdminPanel' */ './AdminPanel'));
AdminPanel.jsx
import * as React from 'react';
const AdminPanel = () => {
return <div>You are an admin!</div>
}
export default AdminPanel;
MyMenu.jsx
import * as React from 'react';
import {useState} from 'react';
import {AdminPanelLazy} from './AdminLazyHelper';
let MyMenu = () => {
let [isAdmin, setIsAdmin] = useState(false);
return <div>
{isAdmin && <Suspense fallback={<>Loading...</>}><AdminPanelLazy /></Suspense>}
</div>
}
这将需要一些服务器端授权来保护与管理相关的脚本不被公开访问,但是如果您希望应用程序真正安全,无论您是否创建单独的捆绑包,您都会遇到这个问题。