首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >nodemailer中的"TypeError:无法读取未定义属性的‘响应’“

nodemailer中的"TypeError:无法读取未定义属性的‘响应’“
EN

Stack Overflow用户
提问于 2020-02-22 10:23:06
回答 2查看 485关注 0票数 0

基本上,我试图向用户发送一个url来重置他的密码。我已经正确地从mailer.js导入了所有的东西,并且在得到响应之前一切都很好。这是说

it can not read property response of undefined.

routes/users.js

router.post("/reset-password/:email", emailController.createResetPasswordToken)

utils/mailer.js

代码语言:javascript
运行
复制
const nodemailer = require("nodemailer")

let transporter = nodemailer.createTransport({
    service: "gmail",
    auth: {
        user: process.env.EMAIL,
        pass: process.env.PASSWORD
    }
})

getPasswordResetURL = (user, token) => {
    return `http://localhost:3000/reset-password/${user._id}/${token}`
}

const resetPasswordTemplate = (user, url) => {
    const from = process.env.EMAIL
    const to = user.email
    const subject = "Password Reset"
    const html = `
        <p>Hey ${user.name || user.email},</p>
        <p>We heard that you forgot your password. Sorry about that!</p>
        <p>But don’t worry! You can use the following link to reset your password:</p>
        <a href=${url}>${url}</a>
        <p>If you don’t use this link within 1 hour, it will expire.</p>
    `
}

module.exports = { transporter, getPasswordResetURL, resetPasswordTemplate }

emailController.js

代码语言:javascript
运行
复制
const User = require("../models/User")
const bcrypt = require("bcrypt")
const jwt = require("jsonwebtoken")
const validator = require("validator")
const { transporter, getPasswordResetURL, resetPasswordTemplate } = require("../utils/mailer")
module.exports = {

    createResetPasswordTokenAndSendMail: (req, res) => {
        const email = req.params.email
            User.findOne({ email }, (err, user) => {
                if (err) console.log(err)
                // res.json({user})
                const hashedPassword = user.password
                const createdAt = user.createdAt
                const userId = user._id
                // console.log(user.password, user.createdAt, userId )
                const secret = hashedPassword + "-" + createdAt
                const token = jwt.sign({ userId }, secret, {
                    expiresIn: 3600
                })
                // console.log(token)
                // console.log(user)
                const url = getPasswordResetURL(user, token) 
                // console.log(url)
                const emailTemplate = resetPasswordTemplate(user, url)
                // console.log(emailTemplate, "l26")

                const sendEmail = () => {
                    transporter.sendMail(emailTemplate, (err, info) => {
                        if (err) console.log(err)
                        // console.log(info, "L31")
                        console.log("email sent successfully", info.response)
                    })
                }
                sendEmail()
        })
    }

}

当我在Postman中测试这个API时,我在控制台中得到了以下错误:

代码语言:javascript
运行
复制
{ Error: Missing credentials for "PLAIN"
    at SMTPConnection._formatError (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:784:19)
    at SMTPConnection.login (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:448:38)
    at connection.connect (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-transport/index.js:271:32)
    at SMTPConnection.once (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:215:17)
    at Object.onceWrapper (events.js:313:30)
    at emitNone (events.js:106:13)
    at SMTPConnection.emit (events.js:208:7)
    at SMTPConnection._actionEHLO (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:1313:14)
    at SMTPConnection._processResponse (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:942:20)
    at SMTPConnection._onData (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:749:14)
    at TLSSocket.SMTPConnection._onSocketData.chunk (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)
    at emitOne (events.js:116:13)
    at TLSSocket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    at TLSSocket.Readable.push (_stream_readable.js:208:10) code: 'EAUTH', command: 'API' }
/home/voidrealm/Desktop/myApp/controllers/emailController.js:32
                        console.log("email sent successfully", info.response)
                                                                    ^

TypeError: Cannot read property 'response' of undefined
    at transporter.sendMail (/home/voidrealm/Desktop/myApp/controllers/emailController.js:32:69)
    at transporter.send.args (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/mailer/index.js:226:21)
    at connection.login.err (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-transport/index.js:282:36)
    at SMTPConnection.login (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:448:24)
    at connection.connect (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-transport/index.js:271:32)
    at SMTPConnection.once (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:215:17)
    at Object.onceWrapper (events.js:313:30)
    at emitNone (events.js:106:13)
    at SMTPConnection.emit (events.js:208:7)
    at SMTPConnection._actionEHLO (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:1313:14)
    at SMTPConnection._processResponse (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:942:20)
    at SMTPConnection._onData (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:749:14)
    at TLSSocket.SMTPConnection._onSocketData.chunk (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)
    at emitOne (events.js:116:13)
    at TLSSocket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)

更新

配置OAuth之后,我将得到相同的错误:

这是我更新的代码。

mailer.js

代码语言:javascript
运行
复制
const nodemailer = require("nodemailer")

let transporter = nodemailer.createTransport({
    service: "gmail",
    auth: {
        type: "OAuth2",
        user: process.env.EMAIL,
        clientId: process.env.clientId,
        clientSecret: process.env.clientSecret,
        refreshToken: process.env.refreshToken,
        accessToken: process.env.accessToken,
        expiresIn: process.env.expiresIn
    }
})

getPasswordResetURL = (user, token) => {
    return `http://localhost:3000/reset-password/${user._id}/${token}`
}

const resetPasswordTemplate = (user, url) => {  
    from = process.env.EMAIL,
    to = user.email,
    subject = "Password Reset",
    auth = {
        user: user.email,
        refreshToken: process.env.refreshToken,
        accessToken: process.env.accessToken,
        expiresIn: process.env.expiresIn
    },
    html = `
        <p>We heard that you forgot your password. Sorry about that!</p>
        <p>But don’t worry! You can use the following link to reset your password:</p>
        <a href=${url}>${url}</a>
        <p>If you don’t use this link within 1 hour, it will expire.</p>
    `
    return {from, to, subject, html, auth}
}

module.exports = { transporter, getPasswordResetURL, resetPasswordTemplate }

emailController.js

代码语言:javascript
运行
复制
const User = require("../models/User")
const bcrypt = require("bcrypt")
const jwt = require("jsonwebtoken")
const validator = require("validator")
const { transporter, getPasswordResetURL, resetPasswordTemplate } = require("../utils/mailer")

module.exports = {

    createResetPasswordTokenAndSendMail: (req, res) => {
        const email = req.params.email
            User.findOne({ email }, (err, user) => {
                if (err) console.log(err)
                // res.json({user})
                const hashedPassword = user.password
                const createdAt = user.createdAt
                const userId = user._id
                // console.log(user.password, user.createdAt, userId )
                const secret = hashedPassword + "-" + createdAt 
                const token = jwt.sign({ userId }, secret, {
                    expiresIn: 3600
                })
                // console.log(token)
                // console.log(user)
                const url = getPasswordResetURL(user, token) 
                // console.log(url)
                const emailTemplate = resetPasswordTemplate(user, url)
                console.log(emailTemplate, "l26")

                const sendEmail = () => {
                    transporter.sendMail(emailTemplate, (err, info) => {
                        if (err) console.log(err)
                        // console.log(info, "L31")
                        console.log("email sent successfully", info.response)
                    })
                }
                sendEmail()
        })
    }
}

控制台

代码语言:javascript
运行
复制
{ Error: invalid_request
    at postRequest (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/xoauth2/index.js:259:33)
    at PassThrough.req.once (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/xoauth2/index.js:328:20)
    at Object.onceWrapper (events.js:313:30)
    at emitNone (events.js:111:20)
    at PassThrough.emit (events.js:208:7)
    at endReadableNT (_stream_readable.js:1064:12)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickCallback (internal/process/next_tick.js:180:9) code: 'EAUTH', command: 'AUTH XOAUTH2' }
/home/voidrealm/Desktop/myApp/controllers/emailController.js:33
                        console.log("email sent successfully", info.response)
                                                                    ^

TypeError: Cannot read property 'response' of undefined
    at transporter.sendMail (/home/voidrealm/Desktop/myApp/controllers/emailController.js:33:69)
    at transporter.send.args (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/mailer/index.js:226:21)
    at connection.login.err (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-transport/index.js:282:36)
    at _auth.oauth2.getToken (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/smtp-connection/index.js:1709:24)
    at generateCallback (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/xoauth2/index.js:111:13)
    at postRequest (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/xoauth2/index.js:259:24)
    at PassThrough.req.once (/home/voidrealm/Desktop/myApp/node_modules/nodemailer/lib/xoauth2/index.js:328:20)
    at Object.onceWrapper (events.js:313:30)
    at emitNone (events.js:111:20)
    at PassThrough.emit (events.js:208:7)
    at endReadableNT (_stream_readable.js:1064:12)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)

Note:我正在获取auth所需的所有凭据值,并将其保存在我的.env文件中。

EN

回答 2

Stack Overflow用户

发布于 2020-02-22 10:38:23

根据this answer的说法,Gmail / Google电子邮件服务需要OAuth2来进行认证。纯文本密码需要在google帐户上手动禁用安全功能。

因此,请确保您从您的帐户禁用安全功能或使用oAuth2。

另外,我不确定您使用的是哪个版本的Nodemail,但是info参数不包含response支柱。它有一个envelope和一个messageId属性。

票数 0
EN

Stack Overflow用户

发布于 2020-02-22 14:02:28

你什么地方都没有宣布运输机。

试着执行下面的代码,

代码语言:javascript
运行
复制
var transporter = nodemailer.createTransport({
  service: 'gmail',
  auth: {
    user: process.env.EMAIL,
    pass: process.env.PASSWORD
  }
});

var mailOptions = {
  const from = process.env.EMAIL
    const to = user.email
    const subject = "Password Reset"
    const html = `
        <p>Hey` + user.name  user.email+`,</p>
        <p>We heard that you forgot your password. Sorry about that!</p>
        <p>But don’t worry! You can use the following link to reset your password:</p>
        <a href=`url`>`url</a>
        <p>If you don’t use this link within 1 hour, it will expire.</p>
    `
};

transporter.sendMail(mailOptions, function(error, info){
  if (error) {
    console.log(error);
  } else {
    console.log('Email sent: ' + info.response);
  }
});

编辑的

更改html格式,就像我在上面的代码中所做的那样。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60351160

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档