基于用户是否有权访问来保护路由



我正在React Router上构建一个(我认为(应该是简单的访问保护,以根据用户是否可以访问该规范来保护路由/spec/:id上的给定spec。用户对规范的访问通过其id: string是否出现在规范的shared: string[]字段中来表示

当用户没有访问权限时,预期的行为是将他们重定向到/的主页。在下面的情况中,用户没有访问权限,相反,我留在/spec/:id,控制台中没有任何错误。有人能指出为什么会出现这种情况吗?非常感谢

import { useContext, useEffect, useState } from "react";
import { Redirect, Route, useParams } from "react-router-dom";
import { getSpecById } from "../Models/Spec";
import { AuthContext } from "../Util/Auth";
const ProtectedRoute = ({ component: Component, ...rest }: any) => {
const { id } = useParams<{ id: string }>();
const {currentUser} = useContext(AuthContext);
const [isOwner, setIsOwner] = useState<boolean>(false);

useEffect(() => {
async function fetchOwnership() {
const specData = await getSpecById(id);
if (specData && currentUser) {
console.log(specData.shared.includes(currentUser.uid)); //logs false
setIsOwner(specData.shared.includes(currentUser.uid));
}
}
fetchOwnership();
});
return (
<Route
{...rest}
render={(routeProps: any) => {
isOwner ? (
<Component {...routeProps} />
) : (
<Redirect to={"/"} />
)
}}
/>
)
};
export default ProtectedRoute

我打电话给<ProtectedRoute>

<ProtectedRoute exact path="/spec/:id" render={() => (<Spec isEdit={true}/> )}/>


EDIT根据Jason的反馈,我重新设计了包含isOwner的状态变量,以使用useRef()。但是Redirect仍然没有被调用。即使isOwner等于false,我也不会被送回"/"

const ProtectedRoute = ({ component: Component, ...rest }: any) => {
const { id } = useParams<{ id: string }>();
const {currentUser} = useContext(AuthContext);
const isOwner = useRef(null);
useEffect(() => {
async function fetchOwnership() {
const specData = await getSpecById(id);
if (specData && currentUser) {
isOwner.current = specData.shared.includes(currentUser.uid);
}
}
fetchOwnership();
});
console.log(isOwner.current);
if (isOwner.current === undefined) {
return null;
}
return (
<Route
{...rest}
render={(routeProps: any) => {
isOwner.current ? (
<Component {...routeProps} />
) : (
<Redirect to={"/"} />
)
}}
/>
)
};

似乎根本没有调用重定向。在第一次渲染中,isOwner为false(useState的默认值(,因此应该立即重定向(如果一切正常(;

我假设Route标记没有呈现其子级。是从{...rest}给它一个path道具吗?

不能直接调用useEffect钩子内的异步函数,必须使用IIFE方法。这是我用过的一个例子。

useEffect(() => {
(async () => {
const users = await axios.get("https://randomuser.me/api/?page=1&results=10&nat=us");
setUsers(users.data.results);
})();
}, []);

在您的情况下是

useEffect(() => {
async function fetchOwnership() {
const specData = await getSpecById(id);
if (specData && currentUser) {
console.log(specData.shared.includes(currentUser.uid)); //logs false
setIsOwner(specData.shared.includes(currentUser.uid));
}
}()

});

最新更新