Nodemailer: invalid_client при использовании Google OAuth2 - PullRequest
0 голосов
/ 24 февраля 2020

Моя функция (развернутая как облачная функция Firebase) использует Nodemailer для отправки электронной почты с помощью Gmail.

  • Я создал служебную учетную запись в консоли CCP project-name@appspot.gserviceaccount.com
  • Я включил Gmail API в консоли GCP для этого проекта https://console.cloud.google.com/apis/library/gmail.googleapis.com
  • Функция использует googleapis для генерации токенов с использованием сервиса Google OAuth 2
  • Функция использует nodemailer используется для отправки электронной почты

Я получаю одну из двух ошибок:

  • Error: invalid_client - при разрешении googleapis генерировать refreshToken и accessToken
  • Can't create new access token for user - при разрешении nodemailer генерировать refreshToken и accessToken

Проблема может быть в моем коде или в том, как установлены учетные данные OAuth в консоли GCP.

function.js

// Based on https://github.com/akshaybhange/Firebase-Functions-sendMail-Google-OAuth2/blob/master/index.js

const nodemailer = require('nodemailer');
const ServiceAccount = require('./config/serviceAccount');
const mailConfig = require('./config/mailConfig');

const { google } = require("googleapis");

exports.sendMail = (subject, message, callback) => {

    // Google APIs start

    const refreshToken = "1//04tRp..."; // Obtained from "https://developers.google.com/oauthplayground"

    const OAuth2 = google.auth.OAuth2;
    const oAuth2Client = new OAuth2(
        ServiceAccount.client_id,
        ServiceAccount.private_key,
        "https://developers.google.com/oauthplayground" // Redirect URL
    );

    oAuth2Client.setCredentials({
        refresh_token: refreshToken
    });
    const accessToken = oAuth2Client.getAccessToken();

    // Google APIs end

    const authOptions = {
        auth: {
            type: 'OAuth2',
            user: ServiceAccount.client_email, // mailConfig.from
            clientId: ServiceAccount.client_id,
            clientSecret: ServiceAccount.private_key,
            refreshToken // from Google API
            accessToken // from Google API
        },
    };

    const transporterOptions = {
        service: "gmail",
        ...authOptions
    };

    const transporter = nodemailer.createTransport(transporterOptions);
    transporter.on('token', token => console.log(token));

    const mailOptions = {
        from: mailConfig.from,
        to: mailConfig.to,
        subject: subject,
        text: message,
        // ...authOptions // read this might help
    };

    return transporter.sendMail(mailOptions, (error, response) => {
        error ? console.error(error) : console.log(info);
        transporter.close();
        return callback ?  callback(error, response) : {error, response};
    });
};

Журнал консоли:

> var {sendMail} = require('./sendMail');
undefined
> sendMail("Subject","Message")
undefined
> (node:88994) UnhandledPromiseRejectionWarning: Error: invalid_client
    at Gaxios.<anonymous> (/Users/User/Developer/Project/functions/node_modules/googleapis/node_modules/gaxios/build/src/gaxios.js:73:27)
    at Generator.next (<anonymous>)
    at fulfilled (/Users/User/Developer/Project/functions/node_modules/googleapis/node_modules/gaxios/build/src/gaxios.js:16:58)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
(node:88994) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:88994) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Error: invalid_client
    at /Users/User/Developer/Project/functions/node_modules/nodemailer/lib/xoauth2/index.js:259:33
    at PassThrough.<anonymous> (/Users/User/Developer/Project/functions/node_modules/nodemailer/lib/xoauth2/index.js:328:20)
    at Object.onceWrapper (events.js:299:28)
    at PassThrough.emit (events.js:210:5)
    at PassThrough.EventEmitter.emit (domain.js:540:23)
    at endReadableNT (_stream_readable.js:1200:12)
    at processTicksAndRejections (internal/process/task_queues.js:80:21) {
  code: 'EAUTH',
  command: 'AUTH XOAUTH2'
}

Журнал консоли - при комментировании API Google и разрешении Nodemailer генерировать refreshToken и accessToken:

> var {sendMail} = require('./sendMail');
undefined
> sendMail("Subject","Message",(error, info)=>{console.log(error,info)})
undefined
> Error: Can't create new access token for user
    at XOAuth2.generateToken (/Users/User/Developer/Project/functions/node_modules/nodemailer/lib/xoauth2/index.js:179:33)
    at XOAuth2.getToken (/Users/User/Developer/Project/functions/node_modules/nodemailer/lib/xoauth2/index.js:123:18)
    at SMTPConnection._handleXOauth2Token (/Users/User/Developer/Project/functions/node_modules/nodemailer/lib/smtp-connection/index.js:1679:27)
    at SMTPConnection.login (/Users/User/Developer/Project/functions/node_modules/nodemailer/lib/smtp-connection/index.js:534:22)
    at /Users/User/Developer/Project/functions/node_modules/nodemailer/lib/smtp-transport/index.js:271:32
    at SMTPConnection.<anonymous> (/Users/User/Developer/Project/functions/node_modules/nodemailer/lib/smtp-connection/index.js:209:17)
    at Object.onceWrapper (events.js:299:28)
    at SMTPConnection.emit (events.js:210:5)
    at SMTPConnection.EventEmitter.emit (domain.js:540:23)
    at SMTPConnection._actionEHLO (/Users/User/Developer/Project/functions/node_modules/nodemailer/lib/smtp-connection/index.js:1298:14) {
  code: 'EAUTH',
  command: 'AUTH XOAUTH2'
} undefined
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...