配置统一免登录页面
2023 年 12 月 22 日
场景
目前星充平台上的对每个页面都做了登录校验,如果没有登录,那么就会直接跳转到登录页面。
但是,我们会存在一些场景:我们对这些页面不需要进行权限校验,不需要登录限制。
思路
- 我们可以在入口文件(
**app.js**
**)**里面进行判断
typescript
/**
* 统一登录,如果使用三方接口方式登录,需要改写改方法
* @param oldRender
*/
export async function render(oldRender: any) {
const loginRes = await ssoGetUserInfo().catch((error) => {
if (error.code === "E00005") {
ssoRedirectFunction();
}
});
oldRender();
}
目前就是上面代码的情况,一旦发现没有登陆,那么就会调用ssoRedirectFunction()
这个函数
所以我们可以在判断之前加一个window.location.pathname
来判断当前前缀(/noNeedToLogin
)是否需要
关于oldRender()
我的理解是:应用程序的渲染函数,用于将应用程序的组件渲染到页面上。
typescript
/**
* 统一登录,如果使用三方接口方式登录,需要改写改方法
* @param oldRender
*/
export async function render(oldRender: any) {
// 如果页面是以/noNeedToLogin的时候,那么不需要登录
if (window.location.pathname === "/noNeedToLogin") {
return;
}
const loginRes = await ssoGetUserInfo().catch((error) => {
if (error.code === "E00005") {
ssoRedirectFunction();
}
});
if (loginRes) {
setStorage("M-USER", JSON.stringify((loginRes as any).model));
getUserPower({
userId: (loginRes as any).model.userId,
}).then((res) => {
// "M-POWER"; "M-RULES";
// const rules = res.model.map((item: { code: string; }) => item.code);
// sessionStorage.setItem("power", JSON.stringify(res.model || []));
// sessionStorage.setItem("rules", JSON.stringify(rules || []));
// setLoginChecked(true);
console.log("res", res);
});
oldRender();
}
}
- 封装,为了后续更好的管理,最好写一个专门的
layout
用于判断,是否需要登录校验
checked
状态,用于判断是否进行了登录判断
- 如果登录状态为`false`,那么会返回`null`,也就是,子组件无法渲染出来
- 如果登录状态为`true`,那么就会渲染出相应的`children`
typescript
import { useLocation } from "umi";
import type React from "react";
import { useEffect, useState } from "react";
import { setStorage } from "@/utils/utils";
import { ssoGetUserInfo, ssoRedirectFunction } from "xxxxxx";
import { getUserPower } from "@/services/login";
/**
* 不用登陆的Layout页面
* @param param
* @returns
*/
const SecurityLayout: React.FC<{ children: React.ReactNode; }> = ({ children }) => {
const location = useLocation();
const [loginChecked, setLoginChecked] = useState(false);
useEffect(() => {
if (!(location.pathname.startsWith("/notNeedToLogin"))) {
ssoGetUserInfo()
.then((loginRes: unknown) => {
setStorage("userInfo", JSON.stringify(loginRes.model));
getUserPower({
userId: loginRes.model.userId,
})
.then((res) => {
const rules = res.model.map((item: { code: string; }) => item.code);
sessionStorage.setItem("power", JSON.stringify(res.model || []));
sessionStorage.setItem("rules", JSON.stringify(rules || []));
setLoginChecked(true);
});
})
.catch((error) => {
if (error.code === "E00005") {
ssoRedirectFunction();
}
});
} else {
setLoginChecked(true);
}
}, [location.pathname]);
if (!loginChecked) {
return null;
}
return children;
};
export default SecurityLayout;
上述一些引用库简单描述:
setStorage
:封装的方法,主要就是用于将数据存在storage
里面ssoGetUserInfo
,ssoRedirectFunction
:内部组件库,用于sso
单点登录getUserPower
:用于权限控制,获取用户的权限
那么在原先处理的地方,就不需要任何的处理,也就是在入口文件的render
里面,不在需要登录的判断,后面的security
页面会进行判断的。
typescript
export async function render(oldRender) {
oldRender(); // 这个render函数中,就不需要写
}
那么我们在配置路由的时候,就要先走SecurityLayout
这个页面
typescript
{
path: "/",
component: "../layouts/SecurityLayout",
routes: [
{
path: "./notNeedToLogin",
component: "../layouts/SecurityLayout",
routes: [
{
path: "./threeCodeBindApp",
name: "三码绑定APP",
component: "../layouts/BlankLayout",
routes: [
{
path: "./home",
name: "三码绑定APP首页",
component: "/src/pages/SupplyPlan/ThreeCodeBindApp",
},
],
},
],
},
{
path: "./",
component: "../layouts/BlankLayout",
routes: [
{
path: "./",
component: "../layouts/BasicLayout",
routes: [
{
name: "主数据",
icon: "money-collect",
key: "MainData",
routes: [
{
path: "/bom",
key: "Bom",
name: "BOM",
},
],
},
],
},
],
},
]
}];