在MVC中重置NodeJS Express密码

时间:2019-04-09 10:46:21

标签: node.js express nodemailer

我正在尝试在节点应用程序中设置 password-reset 路由,该路由假定是通过密码重置链接向用户发送电子邮件。

我遇到的问题是我不断收到错误TypeError: cannot read property json of undefined。据我了解,这意味着我没有正确地将email传递给服务器端代码。

我在查找错误的确切位置时遇到了麻烦。我遵循了this example,但是我将其更改为更多的MVC体系结构。这意味着我已经将 Node 代码拆分为服务控制器

这是我的ReactJS代码:

    class PasswordResetComponent extends Component { 
        constructor(props){
            super(props);
            this.state = {
                email:'',
                showError:false,
                messageFromServer:''
            }
        }
        handleChange = name => event => {
            this.setState({ 
                [name]: event.target.value 
            });
        }
        sendEmail = e => {
            e.preventDefault();
            if(this.state.email == ' '){
                this.setState({
                    showError: false,
                    messageFromServer:' ',
                });
            }else{
                (async () => {
                    const rawResponse = await fetch(process.env.REACT_APP_SERVER_URI + '/user/password-reset', {
                      method: 'POST',
                      body: this.state.email
                    });
                    const response = await rawResponse.json();
                    console.log(response)
                  })();
            }
        }
        render(){
            console.log(this.state.email)
            const {email, messageFromServer, showError, showNullError} = this.state;
            return(
            <div className="container-fluid no-gutters page-login">
                <div className="row">
                    <div className="login-wrapper">
                        <form onSubmit={this.sendEmail} method="POST">
                            <div className="form-row">
                                <div className="form-group col-md-12">
                                    <input type="email" name="email" className="form-control" value={email} onChange={this.handleChange('email')} placeholder="Email" required/>
                                </div>
                            </div>
                                <button type="submit" className="btn btn-primary btn-lg btn-block">Send Confirmation</button>
                        </form>

                        <Link to="/login"><button className="mt-4 btn btn-info">Back to Login</button></Link>
                    </div>
                </div>
            </div>
            );
        }
    }

在我的React代码中,我设法成功打印出this.state.email的值,这意味着它应该可以正常通过。我还在请求中收到200状态。

这是我的密码重设服务:

   exports.passwordResetService = async function(email,res, req){
      try{
        User.findOne({
          email: email
        }).then(user => {
            if( user == null){
              res.json('email not in db');
            }else{
              const token = crypto.randomBytes(20).toString('hex');
              console.log(token);
              user.update({
                resetPasswordToken: token,
                resetPasswordExpires: Date.now() + 360000,
              });

              const transporter = nodemailer.createTransport({
                  service: 'gmx',
                  host: 'mail.gmx.com',
                  port: 587,
                  secure: true,
                  auth: {
                    user: `${process.env.EMAIL_ADDRESS}`,
                    pass: `${process.env.EMAIL_PASSWORD}`,
                  },
              });

              const mailOptions = {
                from:'testaccount9909@gmx.com',
                to: `${user.email}`,
                subject: `Password Reset Email Broh'`,
                text:
                `Please click the following link to reset your account's password:`+
                `http://localhost:3003/reset/${token}\n\n`+
                `If you simply ignore the link, your password will remain unchanged!`
              }
              console.log('sending email...');
              transporter.sendMail(mailOptions, function(err, response){
                if(err){
                  console.error('there was an error: ', err);
                } else {
                  console.log('here is the resposne:', response);
                  res.status(200).json('recovery email sent');
                }
              })

            }
        }).catch(error =>
          console.log(error)
        );
      }catch(e){
        throw Error("And Error occured while resetting the password");
      }
    }

这是我的密码重设控制器:

exports.passwordReset = async function(req, res, next){
  try{
    let passwordResetValue = await UserService.passwordResetService(req.body.email);
    return res.status(200).json({status:200, data: passwordResetValue, error:"false", message:"Password reset email has been sent!"})
  }catch(e){
    console.log(e, "Wopsie wopsie email reset error!");
    res.status(400);
  }
};

我得到错误的地方在服务内部,更具体地说:

    if( user == null){
      res.json('email not in db');
    }
  

为什么我不将用户电子邮件传递给NodeJS服务?

1 个答案:

答案 0 :(得分:1)

获得res的原因是passwordResetServicepasswordResetService不可用,因为您没有从路由回调中传递它,并且它不是中间件

由于您使用// Since you want to send the some success message, you can make a promise wrapper // to return a promise which you can later await to get status or failure function mailSender(mailOptions) { return new Promise((resolve, reject) => { transporter.sendMail(mailOptions, function(err, response){ if(err){ // could just reject(err) instead reject('there was an error: ', err); } else { console.log('here is the resposne:', response); resolve('recovery email sent'); } }); }); } exports.passwordResetService = async function(email){ let mailStatus; try{ const user = User.findOne({ email }); if (user === null) { return ({ message: "email not in db" }); } const token = crypto.randomBytes(20).toString('hex'); console.log(token); user.update({ resetPasswordToken: token, resetPasswordExpires: Date.now() + 360000, }); const transporter = nodemailer.createTransport({ service: 'gmx', host: 'mail.gmx.com', port: 587, secure: true, auth: { user: `${process.env.EMAIL_ADDRESS}`, pass: `${process.env.EMAIL_PASSWORD}`, }, }); const mailOptions = { from:'testaccount9909@gmx.com', to: `${user.email}`, subject: `Password Reset Email Broh'`, text: `Please click the following link to reset your account's password:`+ `http://localhost:3003/reset/${token}\n\n`+ `If you simply ignore the link, your password will remain unchanged!` } console.log('sending email...'); // wait for promise to resolve, if promise is rejected, catch block will catch the error mailStatus = await mailSender(mailOptions); } catch(e) { throw Error("And Error occured while resetting the password"); } return mailStatus; } 所做的全部工作就是进行验证并发送电子邮件,因此您可以对代码进行一些更改,例如:

{{1}}