我正在尝试在节点应用程序中设置 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服务?
答案 0 :(得分:1)
获得res
的原因是passwordResetService
对passwordResetService
不可用,因为您没有从路由回调中传递它,并且它不是中间件
由于您使用// 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}}