【问题标题】:I am trying to confirm the user through the token but its showing an error我正在尝试通过令牌确认用户,但它显示错误
【发布时间】:2019-03-30 04:15:30
【问题描述】:

我对 MERN 全栈了解不多。在这里,我在 nodejs 中有一条从反应前端获取令牌的路由,它在 mongoDb 中找到所需的用户后简单地标记“isVerified = true”。但相反,我收到错误消息,说我的承诺被拒绝了。我不知道是什么原因造成的。我附上了下面的代码。请帮我解决这个问题。

我尝试了多种方法,例如更改请求正文等。但对我没有任何效果。

这是调用路由的动作。

export const verifyUser = (verifyEmail, token, history) => dispatch => {
  axios
    .post(`/api/users/confirmation/${token}`, verifyEmail)
    .then(res => history.push("/login"))
    .catch(err =>
      dispatch({
        type: GET_ERRORS,
        payload: err.response.data
      })
    );
};

这是我的反应表单,要求输入电子邮件,然后进行验证。

import React, { Component } from "react";
import PropTypes from "prop-types";
import { withRouter } from "react-router-dom";
import { connect } from "react-redux";
import { verifyUser } from "../../actions/authActions";
import TextFieldGroup from "../common/TextFieldGroup";

class Confirmation extends Component {
  constructor() {
    super();
    this.state = {
      email: "",
      errors: {}
    };
    this.onChange = this.onChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }

  componentDidMount() {
    if (this.props.auth.isAuthenticated) {
      this.props.history.push("/dashboard");
    }
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.errors) {
      this.setState({ errors: nextProps.errors });
    }
  }

  onChange(e) {
    this.setState({ [e.target.name]: e.target.value });
  }

  onSubmit(e) {
    e.preventDefault();

    const verifyEmail = {
      email: this.state.email
    };

    this.props.verifyUser(verifyEmail, this.props.token, this.props.history);
  }

  render() {
    const { errors } = this.state;
    return (
      <div className="confirmation">
        <div className="container">
          <div className="row">
            <div className="col-md-8 m-auto">
              <h1 className="display-4 text-center">User verification</h1>
              <p className="lead text-center">Enter your email to verify</p>
              <form noValidate onSubmit={this.onSubmit}>
                <TextFieldGroup
                  placeholder="Email"
                  name="email"
                  type="email"
                  value={this.state.email}
                  onChange={this.onChange}
                  error={errors.email}
                />
                <input type="submit" className="btn btn-info btn-block mt-4" />
              </form>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

Confirmation.propTypes = {
  auth: PropTypes.object.isRequired,
  errors: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  auth: state.auth,
  errors: state.errors
});

export default connect(
  mapStateToProps,
  { verifyUser }
)(withRouter(Confirmation));

这是路由器

router.post("/confirmation/:token", (req, res) => {
  Veri.findOne({ token: req.body.token })
    .then(token => {
      if (!token) {
        errors.email =
          "We were unable to find a valid token. Your token may have expired";
        return res.status(400).json(errors);
      }
      User.findOne({ _id: token._userId, email: req.body.email }).then(user => {
        if (!user) {
          errors.email = "We were unable to find a user for this token";
          return res.status(400).json(errors);
        }
        if (user.isVerified) {
          errors.email = "This user has already been verified";
          return res.status(400).json(errors);
        }
        // Verify and save the user
        user.isVerified = true;
        user.save().then(user => res.json(user));
      });
    })
    .catch(function() {
      console.log("Promise Rejected");
    });
});

【问题讨论】:

  • 您应该在 catch 中记录拒绝的原因并尝试分析发生了什么。至少在此处粘贴错误。
  • 您已将 confirmation 路由设置为读取 query param,但在您的路由正文中,您正在从 req.body 读取。将其更改为 req.param.token

标签: node.js reactjs react-redux


【解决方案1】:

除非您设置了一些将查询变量解析为req.body 的 Express 中间件,否则永远不会读取令牌。 req.body 应该是一个只有一个字段的对象:email。您的查询参数位于 req.params 对象中。有理由认为,Veri.findOne({ token: req.body.token }) 承诺会将null 传递给它的回调函数或直接拒绝。无论如何,它没有达到预期的效果。将第一个查询更改为 Veri.findOne({ token: req.params.token }) 应该可以解决主要问题。

也可能是您的 Express 应用中没有正文解析器中间件。如果没有,req.body 将未定义,尝试访问其中的字段将导致 TypeError。确保您使用的是正文解析器来填充 req.body

最后,errors 对象可能是undefined。即使不是,对这样的对象进行变异也被认为是不好的做法。而不是像

这样的一行
errors.email = "... error message"

const errors = { email: "... error message" }

或保持原样并将错误初始化为处理程序顶部的空对象。

router.post("/confirmation/:token", (req, res) => {
  const errors = {}
  ...
})

【讨论】:

  • 感谢您的帮助。我现在已经定义了一个错误字段并且错误消失了,但现在它没有从婴儿车中获取令牌。当我尝试在承诺之后从婴儿车中控制台记录令牌时,它显示令牌为“null”。
  • 您可能发送的是 'null' 而不是前端的令牌。 Condition 组件的 token 属性很可能未定义或为空。将其道具类型设置为string.isRequired 以检查。
  • 是的,我犯了一个语法错误,因此,null 被传递到后端而不是令牌。感谢您的帮助。
猜你喜欢
  • 2021-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-07
  • 1970-01-01
相关资源
最近更新 更多