reactjs - React Router 中的用户身份验证
问题描述
伙计们。我正在学习如何使用 React Router 将 React 与 Express 集成,并且在验证用户时遇到了问题。我正在尝试使用更高阶的组件根据用户的授权状态有条件地呈现受保护的路由。
const ProtectedRoute = ({ component: Component, ...rest }) => {
return (
<Route
{...rest}
render={props => {
if (!AUTHORIZED) {
return <Redirect to="/login" />;
}
return <Component {...props} />;
}}
/>
);
};
我遇到的问题在if (!AUTHORIZED)
声明中。我正在使用 Passport 在 Express 服务器端处理身份验证,并且我设置了一个端点来检索用户信息和授权状态,但我无法弄清楚如何在页面呈现之前访问该数据。如果我使用类组件而不是功能组件(也学习钩子),我认为我可以使用componentWillMount
生命周期方法获取数据,但我读到这是不好的做法。任何关于我如何从这里继续前进的想法将不胜感激!
***编辑*** 我试图让它工作的几件事......我尝试添加一个授权模块来为我获取数据。
class Auth {
constructor() {
this.authenticated = false;
}
async isAuthenticated() {
console.log("hitting auth route");
await fetch("/api/auth")
.then(res => res.json())
.then(json => {
if (json.error) {
this.authenticated = false;
}
this.authenticated = true;
});
return this.authenticated;
}
}
export default new Auth();
我导入模块并auth.authenticated()
代替 placeholder插入AUTHORIZED
。这个函数被跳过了,因为它是异步的,并且重定向总是会发生。所以我需要添加await
到auth.authenticated()
. 但是现在我需要async
更进一步,所以我愚蠢地async
在前面添加了props
这样
render={async props => {
的内容:所以现在它试图渲染一个 Promise 对象而不是一个组件,并且我们一直得到错误Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.
Promises。
解决方案
如果有人遇到类似问题,请回答这个问题......我的第一个解决方案是基于Firealem Erko的评论。登录时,我将带有用户 ID 的变量保存到本地存储并在我的组件中引用它。这是一个很好的第一个解决方案,但后来被他评论中提到的rotimi-best改进了。事实证明,您确实可以将 props 传递给这些组件,这是我没有经验的。所以这就是我现在的做法。最终解决方案如下:
const ProtectedRoute = ({
component: Component,
logged,
setLogged,
...rest
}) => {
return (
<Route
{...rest}
render={props => {
if (!logged) {
return (
<Redirect
to={{
pathname: "/login",
state: { flashInfo: "Please log in to continue." }
}}
/>
);
} else {
return <Component {...props} logged={logged} setLogged={setLogged} />;
}
}}
/>
);
};
这是我传递道具的父组件:
function App() {
let [logged, setLogged] = useState(false);
useEffect(() => {
if (window.localStorage.getItem("qrs")) {
setLogged(true);
} else {
setLogged(false);
}
}, []);
return (
<div className="App">
<BrowserRouter>
<Nav logged={logged} setLogged={setLogged} />
<Switch>
<ProtectedRoute
exact
path="/dashboard"
component={Dashboard}
logged={logged}
setLogged={setLogged}
/>
<Route
path="/register"
exact
render={props => <Register {...props} logged={logged} />}
/>
<Route
path="/login"
exact
render={props => (
<Login {...props} logged={logged} setLogged={setLogged} />
)}
/>
</Switch>
</BrowserRouter>
</div>
);
}
感谢所有评论者的建议!
推荐阅读
- html - 在 HTML 中显示来自 FETCH 的 JSON 数据
- php - 为什么我的 sql 文件是空的,使用 cron 作业进行 sql 备份?
- kubernetes - 访问 Kubernetes 中的附加卷
- cassandra - 在 Cassandra 数据库中定义 UDT 的更好方法
- reactjs - 在生产模式下对 React 进行 Dockerizing:致命错误:接近堆限制的无效标记压缩分配失败 - JavaScript 堆内存不足
- functional-programming - 将匿名函数应用于树 OCaml
- html - 使用媒体查询 css3 隐藏内容时重复 id
- copy - 如何使用 VBA 轻松复制/粘贴/清除 100 多列的所有其他列范围
- c# - 创建通用对象的非通用工厂
- react-native - 如何在 Material Top Tab Navigator 中为屏幕添加静态背景图像?