我对JavaScript框架还很陌生,但是我仍然不确定很多有关它的内容。 所以我的问题几乎是,当我单击登录表单的“提交”按钮时,它的行为就好像它已成功登录一样。尽管在网络响应中进行了检查,它要么说
“无法读取null的属性'password'”
如果您键入的用户不存在,但
“玩家不存在。”
密码输入错误。
后端的models / Players.js
players.post('/login', async (req, res) => {
console.log(req.body);
await Player.findOne({
where: {
username: req.body.username
}
})
.then(player => {
if(bcrypt.compareSync(req.body.password, player.password)) {
let playertoken = jwt.sign(player.dataValues, process.env.SECRET_KEY, { expiresIn: 1440 });
res.json({ playertoken: playertoken });
} else {
res.send("Player does not exist.");
}
})
.catch(err => {
res.send("Error: " + err);
})});
前端的UserFunctions.js
export const login = player => {
return axios
.post('http://localhost:4000/players/login', {
username: player.username,
password: player.password
})
.then(response => {
localStorage.setItem('playertoken', response.data);
return response.data;
})
.catch(err => {
console.log(err);
throw err;
});};
Homepage.js
import React, { Component } from 'react';
import { login } from '../../UserFunctions'
import './HomePage.css';
class HomePage extends Component {
constructor(props){
super(props);
this.state = {
username: '',
password: '',
errors: {}
};
this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
onChange(e) {
this.setState({ [e.target.name]: e.target.value })
}
onSubmit(e) {
e.preventDefault();
const player = {
username: this.state.username,
password: this.state.password
};
login(player).then(res => {
if (res) {
this.props.history.push('/')
}
})
}
render() {
const nLoggedInText = (
<h4>Please Log in.</h4>
);
const loggedInText = (
<div>
<h4>In here you will be able to track your training progress, match stats and body comparisons.</h4>
<h4>You may now begin tracking your progress have fun!</h4>
</div>
);
const logInForm = (
<div className="row d-flex justify-content-center">
<div className="col-lg-3 rounded border">
<form onSubmit={this.onSubmit} className="m-3">
<div className="form-group">
<label htmlFor="username">Username</label>
<input
className="form-control"
name="username"
placeholder="username"
value={this.state.username}
onChange={this.onChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input
className="form-control"
type="password"
name="password"
placeholder="password"
value={this.state.password}
onChange={this.onChange}
required
/>
</div>
<button type="submit" className="btn btn-bulldogs">Log In</button>
</form>
</div>
</div>
);
return (
<div className="container">
<h1 className="nBrand">BULLDOGS</h1>
<h3>Welcome {}!</h3>
{localStorage.playertoken ? loggedInText : nLoggedInText}
{!localStorage.playertoken ? logInForm : null}
</div>
);
}}
export default HomePage;
答案 0 :(得分:0)
所以,我的问题几乎是,当我单击登录表单的“提交”按钮时,就好像它已成功登录一样。 [即使有错误。]
我将假设您的UserFunctions.js正在运行.then
即使您的服务器发送了错误。 Axios将在以下情况下拒绝请求的承诺
您从200-299范围之外的服务器发送错误代码。默认为200
快速发送回复时的状态代码。我们可以将您的状态码之一更改为未经授权的
带有res.status(401)
的http状态码(即401),基本上可以告诉您的前端
认证时出错(也可以用来表示用户未通过认证)
以使用特定资源)。这是其他状态代码及其含义的列表
有用的:Wikipedia's HTTP Status Code List。
另一个对您的代码有帮助的状态是500状态代码 内部服务器错误。您基本上可以在以下情况下发送此邮件: 请求,服务器无法处理该请求。
接下来的两件事仅是建议,请随时服用。你越来越
“无法读取null的属性'password'”,因为player
中的player.password
是null
。
这意味着您查找用户Player.findOne的电话找不到该用户
用户名,因此返回null。您只需要添加检查以查看播放器是否存在。
最后一件事,最好是通常不要发送意外的内部服务器错误和错误对象 到客户端,而是将它们记录在服务器控制台中并发送回通用响应。 这主要是出于安全原因。
因此,让我们在服务器代码中更改这些内容:
players.post('/login', async (req, res) => {
console.log(req.body);
await Player.findOne({
where: {
username: req.body.username
}
})
.then(player => {
if(player && bcrypt.compareSync(req.body.password, player.password)) {
let playertoken = jwt.sign(player.dataValues, process.env.SECRET_KEY, { expiresIn: 1440 });
res.json({ playertoken: playertoken });
} else {
res.status(401).send("Wrong user password combination.");
}
})
.catch(err => {
console.error(err);
res.status(500).send("Something unexpected happened.");
})});
如果发生错误,您可能还希望将错误发送给用户。这个
可以使用您已经配置的errors
状态来完成。一些
下面的代码已被删除,只是为了更好地向您突出显示已更改的内容。
// ...redacted...
class HomePage extends Component {
// ...redacted...
onSubmit(e) {
// ...redacted...
login(player).then(res => {
if (res) {
this.props.history.push('/')
}
})
.catch(err => {
this.setState({
errors: err,
})
})
}
render() {
// ...redacted...
return (
<div className="container">
<h1 className="nBrand">BULLDOGS</h1>
<h3>Welcome {}!</h3>
{this.state && this.state.errors && this.state.errors.message && <h4>Errors: {this.errors.message}}</h4>}
{/* ...redacted */}
</div>
);
}}
export default HomePage;