我正在使用React with Node&;express和Authentication with passport和passport local,我想知道如何在React中保护路由,我的意思是我只想在用户通过身份验证时显示组件,否则我想要它在登录页面上重定向。
在我的情况下,我想保护Notes路由,我正在尝试的方法根本不起作用。。。
我的React代码
import React from 'react';
import { Switch, Route, Redirect } from 'react-router-dom';
import axios from 'axios';
import Register from './Components/Register';
import Login from './Components/Login';
import Notes from './Components/Notes';
function App () {
//Function to check authentication from server
const checkAuth = () => {
axios.get('http://localhost:8000/notes', { withCredentials : true })
.then(res => res.data)
}
return (
<Switch>
<Route exact path='/' component={Register} />
<Route exact path='/login' component={Login} />
<Route exact path='/notes' render={() => {
return checkAuth()? (
<Notes />
) : (
<Redirect to="/login" />
)
}} />
</Switch>
);
};
export default App;
和我的服务器端代码
//Notes Page
router.get('/notes', (req, res) => {
if(req.isAuthenticated()) {
res.send(req.user.email);
}else{
res.send(false);
}
};
替换下面的代码
<Route exact path='/notes' render={() => {
checkAuth()? (
<Notes />
) : (
<Redirect to="/login" />
)
}} />
请使用此代码
<Route exact path="/notes">{checkAuth ? <Notes /> : <Redirect to="/login" />}</Route>
通过“服务器请求”检查登录状态需要时间!然后考虑创建一个带有State!的类,下面给出一个例子:
import React, { Component } from 'react';
import { Switch, Route, Redirect } from 'react-router-dom';
import axios from 'axios';
import Register from './Components/Register';
import Login from './Components/Login';
import Notes from './Components/Notes';
class App extends Component {
state = {
login: false
}
componentDidMount() {
//Function to check authentication from server
this.checkAuth()
}
checkAuth = () => {
// API request to check if user is Authenticated
axios.get('http://localhost:8000/notes', { withCredentials : true })
.then( res => {
console.log(res.data);
// API response with data => login success!
this.setState({
login: true
});
});
}
render() {
let protectedRoutes = null;
if(this.state.login === true) {
// if login state is true then make available this Route!
protectedRoutes = <Route exact path='/notes' component={Notes} />
}
return (
<Switch>
<Route exact path='/' component={Register} />
<Route exact path='/login' component={Login} />
{ protectedRoutes }
</Switch>
);
}
};
export default App;
我希望这个例子对你有用。
由于函数checkauth
进行网络调用可能无法及时返回正确的值进行呈现,因此您应该做的是创建一个状态,说明用户是否经过身份验证,并让checkauth
更新该状态。
const [authenticated, updateAuthenticated] = useState(false);
。。。更新您的checkAuth以更新已验证的状态
//Function to check authentication from server
const checkAuth = () => {
axios.get('http://localhost:8000/notes', { withCredentials : true })
.then(res => updateAuthenticated(res.data)); // double check to ensure res.data contains the actual value returned
}
。。。更新您的呈现以使用状态
<Route exact path='/notes' render={() => {
return (authenticated ?
(<Notes />)
:
(<Redirect to="/login" />)
)
}} />
。。。使用这种方法,您还可以将useStation
中的默认值设置为true或false,并确定是否是您的服务器端代码造成了麻烦
。。。dont for get调用位于顶部的UseEffect
中的CheckAuth
useEffect(()=>{
checkAuth()
},[])