我有一些受保护的路由器,但是我需要保持页面刷新的状态。
import React from 'react'
import { Route, Redirect, Switch } from 'react-router-dom'
const auth = {
isAuthenticated: true // this would be an http call to get user data
}
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={(props) => (
auth.isAuthenticated === true
? <Component {...props} />
: <Redirect to="/login" />
)} />
)
const Main = () => {
return (
<Switch>
<Route path="/login" exact strict component={Login}/>
<Route path="/logout" exact strict component={Logout}/>
<PrivateRoute path="/profile" exact strict component={Profile}/>
</Switch>
)
}
export default Main
我应该在哪里拨打服务电话?在主应用程序中?在上下文中?
更新:我在Main中添加了一个检查,该检查调用了发送已存储的令牌的api。该调用可能返回200或401
const auth = {
isAuthenticated: Api.status() // this is just a fetch to /status endpoint
.then(
status => {
console.log(status);
return true;
},
error => {
console.log(error);
return false;
}
)
}
但是当我点击/ profile时,它立即将我重定向到登录名(因为isAuthenticated为false)
我的问题完全基于以下情况:用户刷新页面(F5),其他情况运行良好。抱歉,如果我不太清楚,很高兴再次澄清任何事情!
答案 0 :(得分:1)
我认为最好的方法是local storage
将令牌保存在那里,在应用的根组件中的componentDidMount()
中调度一个动作,并将令牌存储在readucer state
答案 1 :(得分:0)
您可以实现如下所示的身份验证上下文:https://usehooks.com/useAuth/
另外将用户存储在 localStorage(或您偏好的存储)中,当 auth-context 挂载时从 localStorage 读取并设置初始值,如下所示:
const [user, setUser] = useState(JSON.parse(localStorage.getItem('user')));
这样,受保护的路由将在重新加载页面时自动重定向(或在经过身份验证的状态下它们应该执行的任何操作)。
答案 2 :(得分:-1)
在这种情况下,我将创建一个AuthContext组件。通过使用上下文提供程序,您可以在应用程序中的所有位置访问用户的登录状态。
import { createContext } from 'react';
const AuthContext = createContext({
token: null,
userId: null,
login: () => {},
logout: () => {}
});
export default AuthContext;
并在您的应用程序的最高级别提供此功能。
import React, { useState } from 'react';
import { Route, Switch } from 'react-router-dom';
import AuthContext from './context/AuthContext';
function App() {
const [token, setToken] = useState(null);
const [userId, setUserId] = useState(null);
const login = (token, userId) => {
setToken(token);
setUserId(userId);
};
const logout = () => {
setToken(null);
setUserId(null);
};
return (
<Switch>
<Route path="/login" exact strict component={Login}/>
<Route path="/logout" exact strict component={Logout}/>
<PrivateRoute path="/profile" exact strict component={Profile}/>
</Switch>
)
}
export default App;
然后以登录/注销形式调用数据库或本地存储。
import React, { useContext } from 'react';
import AuthContext from '../context/AuthContext';
function Auth() {
const { login } = useContext(AuthContext);
const submitHandler = () => {
// Make the call here
};
return (
<Form onSubmit={submitHandler}>
// Put your login form here
</Form>
);
}
export default Auth;