【发布时间】:2020-07-11 22:47:50
【问题描述】:
我正在使用 MERN 堆栈来开发网站。我使用 passport.js 进行本地身份验证。用户通过前端'/login' 上的登录表单登录。一旦用户单击提交按钮,我将阻止其默认行为并在后端的'/login' 发送 axios 发布请求。用户通过身份验证后,我将用户发送到前端的'/products'。要知道用户是否通过身份验证,我在compoundDidMount() 函数的后端的'/login' 发送一个axios get 请求,如果用户通过身份验证,则将状态属性loggedIn 设置为true,否则false .如果我再次访问前端的'/login' 路由,我应该被重定向到前端的'/products',而不根据render() 函数中的代码呈现else 语句(登录表单)中的代码。但首先,else 语句(登录表单)中的代码被渲染了几分之一秒,然后它在'/products' 上渲染组件。为什么会这样?我不希望登录后在访问前端的'/login' 路由时呈现登录表单。这是我的代码。
login.js(登录组件)
import React, { Component } from 'react';
import {Redirect} from 'react-router-dom';
import axios from 'axios';
class Login extends Component {
state = {
email: "",
password: "",
loggedIn: false
}
handleLogin = event => {
event.preventDefault();
const data = {
email: this.state.email,
password: this.state.password
};
axios.post('/login', data)
.then(response => {
// console.log("response status code: ", response.status);
if(response.status === 200) {
// this.setState({loggedIn: true});
this.props.history.push('/products');
}
})
.catch(error => console.log('error is :', error));
}
handleChange = event => {
const property = event.target.name,
value = event.target.value;
this.setState({[property]: value});
}
componentDidMount() {
this.getLoggedInStatus();
}
getLoggedInStatus = () => {
axios.get('/login')
.then(response => {
console.log("response.data is: ", response.data.loggedIn);
this.setState({loggedIn: response.data.loggedIn});
// if(response.data.loggedIn)
// this.props.history.push('/products');
})
.catch(error => console.log("error is : ", error));
// return loggedIn;
}
render() {
// this.getLoggedInStatus();
// console.log("loggedIn is: ", this.state.loggedIn);
if(this.state.loggedIn) {
console.log('Working');
return <Redirect to="/products" />
}
else {
console.log('not working');
return (
<div className="container d-flex justify-content-center mt-5">
<form className="w-50 mt-2" action="/login" method="POST" onSubmit={this.handleLogin}>
<div className="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" className="form-control" name="email" onChange={this.handleChange} id="exampleInputEmail1" aria-describedby="emailHelp" required/>
<small id="emailHelp" className="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div className="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" className="form-control" name="password" onChange={this.handleChange} id="exampleInputPassword1" required/>
</div>
<button type="submit" className="btn btn-primary">Submit</button>
</form>
</div>
);
}
}
}
export default Login;
后端代码
router.get('/login', (request, response) => {
response.json({loggedIn: request.isAuthenticated()});
});
router.post('/login', passport.authenticate('local'), (request, response) => {
if(request.isAuthenticated())
// response.json('successful login');
response.status(200).send({message: 'successful login'});
else {
console.log('Not authenticated');
response.status(404).send({message: 'unsuccessful login'});
}
});
【问题讨论】:
-
我会建议保留用户是否登录的信息,而不是在 localStorage 中并且在 componentDidMount 中进行调用之前,检查数据是否存在于本地存储中,如果是,不要直接调用后端重定向 else 调用 backend 。这将减少不必要的后端调用的延迟!
标签: javascript reactjs async-await