简体   繁体   English

TypeError:在node.js中使用aws-sdk发送电子邮件时,密钥必须是缓冲区

[英]TypeError: Key must be a buffer when sending an email with aws-sdk in node.js

I'm trying to set up an emailing system with nodemailer that's agnostic of the transport type it uses. 我正在尝试使用nodemailer设置一个电子邮件系统,该系统与它使用的传输类型无关。

Here's how I'm trying to send the email: 以下是我尝试发送电子邮件的方式:

const config = require('config')
const mailerConfig = config.get('mailer')
const transporter = nodemailer.createTransport(mailerConfig.transport)
transporter.sendMail({
  from: mailerConfig.from,
  to: toEmail,
  subject,
  text: textBody,
  html: htmlBody,
})

And here's how my config file looks like: 这是我的config文件的样子:

const AWS = require('aws-sdk')
module.exports = {
  mailer: {
    from: 'test_sender@domain.com',
    transport: {
      SES: new AWS.SES({
        accessKeyId: 'secret-key',
        secretAccessKey: 'access-key',
        region: 'region',
      }),
    },
  }
}

Then, whenever I try to send an email, I get the following error: 然后,每当我尝试发送电子邮件时,都会收到以下错误:

error:  TypeError: Key must be a buffer
    at new Hmac (crypto.js:117:16)
    at Object.Hmac (crypto.js:115:12)
    at Object.hmac (/Users/sebi/Work/node_modules/aws-sdk/lib/util.js:401:30)
    at Object.getSigningKey (/Users/sebi/Work/node_modules/aws-sdk/lib/signers/v4_credentials.js:59:8)
at V4.signature (/Users/sebi/Work/node_modules/aws-sdk/lib/signers/v4.js:97:36)
at V4.authorization (/Users/sebi/Work/node_modules/aws-sdk/lib/signers/v4.js:92:36)
at V4.addAuthorization (/Users/sebi/Work/node_modules/aws-sdk/lib/signers/v4.js:34:12)
at /Users/sebi/Work/node_modules/aws-sdk/lib/event_listeners.js:215:18
at finish (/Users/sebi/Work/node_modules/aws-sdk/lib/config.js:320:7)
at /Users/sebi/Work/node_modules/aws-sdk/lib/config.js:338:9
at /Users/sebi/Work/node_modules/aws-sdk/lib/credentials.js:123:23
at Credentials.refresh (/Users/sebi/Work/node_modules/aws-sdk/lib/credentials.js:194:5)
at Credentials.get (/Users/sebi/Work/node_modules/aws-sdk/lib/credentials.js:121:12)
at getAsyncCredentials (/Users/sebi/Work/node_modules/aws-sdk/lib/config.js:332:24)
at Config.getCredentials (/Users/sebi/Work/node_modules/aws-sdk/lib/config.js:352:9)
at Request.SIGN (/Users/sebi/Work/node_modules/aws-sdk/lib/event_listeners.js:192:22)

Please note that when I'm instantiating AWS.SES() in the same place where I'm sending the email, the code works fine. 请注意,当我在我发送电子邮件的同一个地方实例化AWS.SES()时,代码工作正常。 Is there anything special that config does to break the code? config有什么特别的东西可以打破代码吗?

Is there anything special that config does to break the code? 配置有什么特别的东西可以打破代码吗?

Exactly. 究竟。 config package deep-merges all configs. config包深度合并所有配置。 So it walks thru your config, and breaks object returned from AWS.SES() . 所以它AWS.SES()你的配置,并打破从AWS.SES()返回的对象。 You can try to put your keys in config, and apply them to ses only on usage: 您可以尝试将密钥置于配置中,并仅在使用时将其应用于ses

const AWS = require('aws-sdk')
module.exports = {
  mailer: {
    from: 'test_sender@domain.com',
    transport: {
      SES: {
        accessKeyId: 'secret-key',
        secretAccessKey: 'access-key',
        region: 'region',
      },
    },
  }
}

And use it: 并使用它:

const config = require('config')
const mailerConfig = config.get('mailer')
const transporter = nodemailer.createTransport({
    SES: new AWS.SES(mailerConfig.transport.SES)
})
transporter.sendMail({
  from: mailerConfig.from,
  to: toEmail,
  subject,
  text: textBody,
  html: htmlBody,
})

As alternative you can require your config file directly: 作为替代方案,您可以直接要求配置文件:

const config = require('./config') // depends on your files structure

在我的情况下,accessKey和secretAccessKey是未定义的。

I'm one of the maintainers of node-config . 我是node-config的维护者之一。 It sounds like it may be an issue that node-config has added some methods to your configuration object when you just want the plain data back. 听起来这可能是一个问题,当你只想要恢复普通数据时, node-config已经为你的配置对象添加了一些方法。

Since v1.27.0 , config.util.toObject(someValue) was added to allow you to get back a plain old JavaScript object for a given config value. 从v1.27.0开始 ,添加了config.util.toObject(someValue)以允许您为给定的配置值返回一个普通的旧JavaScript对象。 It's documented on our utils wiki page 它记录在我们的utils wiki页面上

If you have an older version of node-config and don't want to upgrade, you also do this on a config structure returned by node-config : 如果你有一个较旧版本的node-config并且不想升级,你也可以在node-config返回的配置结构上执行此操作:

var plainOldValue = JSON.parse(JSON.stringify(configValue)

That has the effect of removing the methods added by node-config and is exactly what the new .toObject() method does internally. 这具有删除node-config添加的方法的效果,并且正是新的.toObject()方法在内部执行的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM