1. 整体架构设计
- 路由配置层:在Solid.js的路由配置中,为每个路由添加权限相关的元数据,例如:
import { Route, Routes } from '@solidjs/router';
const routes = (
<Routes>
<Route path="/admin/dashboard" element={<AdminDashboard />} meta={{ requiresRole: 'admin' }} />
<Route path="/user/profile" element={<UserProfile />} meta={{ requiresRole: ['admin', 'user'] }} />
<Route path="/public/home" element={<Home />} meta={{ requiresRole: null }} />
</Routes>
);
- 权限校验层:创建自定义路由钩子函数来进行权限校验。这个钩子函数将在路由切换时被调用,检查当前用户的角色是否具有访问目标路由的权限。
- 处理层:当权限不足时,需要有相应的处理逻辑,如重定向到特定的提示页面或显示弹窗提示用户无权限访问。
2. 权限校验逻辑
- 获取用户角色:可以通过从本地存储、cookie或者后端接口获取当前用户的角色信息。假设我们有一个函数
getUserRole
来获取用户角色:
function getUserRole() {
// 这里假设从本地存储获取角色
return localStorage.getItem('userRole');
}
- 自定义路由钩子:创建一个自定义的Solid.js路由钩子函数
useRouteGuard
:
import { createEffect } from 'solid-js';
import { useLocation } from '@solidjs/router';
function useRouteGuard() {
const location = useLocation();
const userRole = getUserRole();
createEffect(() => {
const routeMeta = location.route.meta;
if (routeMeta.requiresRole) {
const requiredRoles = Array.isArray(routeMeta.requiresRole) ? routeMeta.requiresRole : [routeMeta.requiresRole];
if (!requiredRoles.includes(userRole)) {
// 权限不足处理
handlePermissionDenied();
}
}
});
}
- 在应用中使用钩子:在应用的顶层组件(如
App
组件)中使用这个钩子:
import { render } from'solid-js/web';
import { Routes } from '@solidjs/router';
import { useRouteGuard } from './useRouteGuard';
const App = () => {
useRouteGuard();
return (
<Routes>
{/* 路由配置 */}
</Routes>
);
};
render(() => <App />, document.getElementById('root'));
3. 处理权限不足的情况
- 重定向:可以将用户重定向到一个权限不足提示页面。假设我们有一个
PermissionDeniedPage
组件和一个重定向函数 redirect
:
import { redirect } from '@solidjs/router';
import { PermissionDeniedPage } from './PermissionDeniedPage';
function handlePermissionDenied() {
redirect('/permission-denied');
}
- 弹窗提示:也可以通过显示一个弹窗来提示用户权限不足。例如使用一个状态管理库(如
valtio
)来控制弹窗的显示:
import { proxy, useSnapshot } from 'valtio';
const state = proxy({
showPermissionDeniedPopup: false
});
function handlePermissionDenied() {
state.showPermissionDeniedPopup = true;
}
const App = () => {
const snap = useSnapshot(state);
return (
<>
{snap.showPermissionDeniedPopup && <PermissionDeniedPopup />}
{/* 其他组件 */}
</>
);
};