在没有手动浏览器身份验证的情况下,如何通过Meteor.js应用程序对(Gmail)API进行身份验证(2)?

时间:2020-01-15 11:27:03

标签: node.js authentication meteor oauth-2.0 gmail-api

我想在没有手动浏览器身份验证的情况下登录我的流星服务器程序。因此,身份验证必须全部自动化。我根本不需要用户干预/互动。 我遇到了答案here,但是它在Java中,我不知道它是否有效。有人可以在meteor.js中提供答案吗?如果答案是在node.js中并且可以在流星上工作,那也很好。

最好是我想使用msavin / SteveJobs pacjage在后台运行此流星代码作为作业的一部分。

1 个答案:

答案 0 :(得分:0)

下面是纯node.js中的有效代码段

功能:

您可以使用Gmail API

使其适应您的需求。

如果您在此示例中遇到麻烦,请尝试Node.js Quickstart Guide

以下是代码段:

const fs = require('fs');
const readline = require('readline');
const { google } = require('googleapis');

// If modifying these scopes, delete token.json.
const SCOPES = [
  'https://mail.google.com/',
  'https://www.googleapis.com/auth/gmail.modify',
  'https://www.googleapis.com/auth/gmail.compose',
  'https://www.googleapis.com/auth/gmail.send'
];
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
const TOKEN_PATH = 'token.json';

/**
 * Create an OAuth2 client with the given credentials, and then execute the
 * given callback function.
 * @param {Object} credentials The authorization client credentials.
 * @param {function} callback The callback to call with the authorized client.
 */
function authorize(credentials, callback) {
  const { client_secret, client_id, redirect_uris } = credentials.installed;
  const oAuth2Client = new google.auth.OAuth2(
    client_id, client_secret, redirect_uris[0]);

  // Check if we have previously stored a token.
  fs.readFile(TOKEN_PATH, (err, token) => {
    if (err) return getNewToken(oAuth2Client, callback);
    oAuth2Client.setCredentials(JSON.parse(token));
    callback(oAuth2Client);
  });
}

/**
 * Get and store new token after prompting for user authorization, and then
 * execute the given callback with the authorized OAuth2 client.
 * @param {google.auth.OAuth2} oAuth2Client The OAuth2 client to get token for.
 * @param {getEventsCallback} callback The callback for the authorized client.
 */
function getNewToken(oAuth2Client, callback) {
  const authUrl = oAuth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: SCOPES,
  });
  console.log('Authorize this app by visiting this url:', authUrl);
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });
  rl.question('Enter the code from that page here: ', (code) => {
    rl.close();
    oAuth2Client.getToken(code, (err, token) => {
      if (err) return console.error('Error retrieving access token', err);
      oAuth2Client.setCredentials(token);
      // Store the token to disk for later program executions
      fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
        if (err) return console.error(err);
        console.log('Token stored to', TOKEN_PATH);
      });
      callback(oAuth2Client);
    });
  });
}

/********************************************************************************************
*********************************************************************************************
*********************************************************************************************
 * Custom edits here
 */

let labelList = [];

function listLabels(auth) {

  const gmail = google.gmail({ version: 'v1', auth });

  gmail.users.labels.list({
    userId: 'me',
  }, (err, res) => {

    if (err) return console.log('The API returned an error: ' + err);

    const labels = res.data.labels;

    if (labels.length) {
      labels.forEach((label) => {
        labelList.push(`${label.name}`);
      });
    } else {
      console.log('No labels found.');
    }

  });

  console.log('===listLabels finished===');

}

function makeEmailBody(to, from, subject, message) {

  let str = [
    "Content-Type: text/plain; charset=\"UTF-8\"\n",
    "MIME-Version: 1.0\n",
    "Content-Transfer-Encoding: 7bit\n",
    "to: ", to, "\n",
    "from: ", from, "\n",
    "subject: ", subject, "\n\n",
    message
  ].join('');

  let encodedMail = new Buffer(str).toString("base64").replace(/\+/g, '-').replace(/\//g, '_');

  return encodedMail;

}

function sendMessage(auth) {

  let raw = makeEmailBody(
    /* to */'email@gmail.com',
    /* from */'email@gmail.com',
    /* subject */'Subject',
    /* message */`Labels:
      ${labelList}
    `);

  const gmail = google.gmail({ version: 'v1', auth });

  gmail.users.messages.send({
    auth: auth,
    userId: 'me',
    resource: {
      raw: raw
    }
  }, (err, res) => {
    return (err || res)
  });

  console.log('===SendMessage finished===');

}

let userId = 'email@gmail.com';
let messageId = '__id__'; 

function getEmail(auth){

  const gmail = google.gmail({ version: 'v1', auth });

  gmail.users.messages.get({
    id: messageId,
    userId: userId,
    format: 'full'
  }, (err, res) => {
    if (err) return console.log('The API returned an error: ' + err);
    console.log(res.data);
  });

  console.log('===listLabels finished===');

}

// RUN script
fs.readFile('credentials.json', (err, content) => {

  if (err) {
    console.log('Error loading client secret file: ' + err);
    return;
  }

  authorize(JSON.parse(content), getEmail);

  // authorize(JSON.parse(content), listLabels);
  // authorize(JSON.parse(content), listFiles);
  // authorize(JSON.parse(content), sendMessage);

});

如何创建服务帐户:

  1. Admin Console中创建项目
  2. 创建service account
  3. 转到管理控制台>安全性>高级设置> Manage API client access
  4. 在“客户名称”中输入您创建的服务帐户的完整电子邮件地址
  5. 在一个或多个API范围中放入https://mail.google.com/,然后单击“授权”
  6. 回到Service accounts,选择您的帐户,启用G Suite域范围委派
  7. 创建服务帐户密钥(将其下载为.json)
  8. 为您的项目激活Gmail API。转到API和服务> Dashboard,单击“启用API和服务”,搜索Gmail并启用它。

现在您已经拥有服务帐户,您可以在项目中使用它。