即使使用错误的凭据也能成功登录吗?

时间:2019-12-08 23:17:34

标签: mysql node.js reactjs express

我对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;

homepage

login

1 个答案:

答案 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.passwordnull。 这意味着您查找用户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;