TypeError: Ключ должен быть буфером при отправке электронного письма с aws-sdk в node.js

Я пытаюсь настроить систему электронной почты с nodemailer это агностик транспортного типа, который он использует.

Вот как я пытаюсь отправить электронное письмо:

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,
})

А вот как мой 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',
      }),
    },
  }
}

Затем, когда я пытаюсь отправить электронное письмо, я получаю следующую ошибку:

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)

Обратите внимание, что когда я создаю экземпляр AWS.SES() там же, куда я отправляю письмо, код работает нормально. Есть ли что-то особенное, что config нарушает код?

3 ответа

Решение

Есть ли что-то особенное, что config делает, чтобы сломать код?

Именно так. config пакет глубоко сливает все конфиги. Так что он проходит через ваш конфиг, и ломает объект, возвращенный из AWS.SES(), Вы можете попытаться поместить свои ключи в конфигурацию и применить их к ses только на использование:

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

И использовать это:

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,
})

В качестве альтернативы вы можете запросить ваш конфигурационный файл напрямую:

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

В моем случае accessKey и secretAccessKey не были определены.

Я один из тех, кто поддерживает node-config, Похоже, это может быть проблемой, которая node-config добавил несколько методов к вашему объекту конфигурации, когда вы просто хотите вернуть простые данные.

Начиная с версии 1.27.0, config.util.toObject(someValue) был добавлен, чтобы вы могли получить простой старый объект JavaScript для заданного значения конфигурации. Это задокументировано на нашей вики-странице.

Если у вас есть старая версия node-config и не хотите обновляться, вы также делаете это в структуре конфигурации, возвращаемойnode-config:

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

Это приводит к удалению методов, добавленных node-config и это именно то, что новый .toObject() метод делает внутренне.

Другие вопросы по тегам