【问题标题】:How do I oauth (2) authenticate to GMail-api from a Meteor.js app without manual browser authentication?如何在没有手动浏览器身份验证的情况下从 Meteor.js 应用程序对 GMail-api 进行 oauth (2) 身份验证?
【发布时间】:2020-05-02 03:56:19
【问题描述】:

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

最好我想在后端运行这个流星代码,作为使用 msavin /SteveJobs pacjage 的作业的一部分。

【问题讨论】:

  • 请添加一些您已经实现的代码。如果您完全不知道从哪里开始,您可以查看帐户包的代码,这些包是 GitHub 上 Meteor 存储库的一部分。
  • @Jankapunkt,请注意我说的是登录和使用 gmail-api。一个例子是 github.com/Slava/meteor-gmail 。我不是在处理包含 accounts-google 包的帐户包。我想使用 gmail api,它提供了许多我无法从 accounts-google 包中获得的功能。如果我误解了你,请告诉我。感谢您的回复。
  • 这是完全相同的 oauth 工作流程,但配置或多或少有所不同。从 oauth 的角度来看,Meteor 服务器也只是一个“客户端”。那么,你到底卡在哪里了?为什么不将您的凭据存储在 settings.json 中并在启动时使用来自 meteor-gmail 链接的 API 加载它们?
  • 所以我有github.com/meteor/meteor/tree/devel/packages;我在上面的链接中看哪里?我上面的链接有错吗?
  • 希望在 Gmail API 中使用哪些操作?你在读/写用户数据吗?

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


【解决方案1】:

下面是简单的node.js的工作sn-p

功能:

您可以使用Gmail API 调整它以满足您的需求

如果您对这个示例感到困惑,请尝试Node.js Quickstart Guide

这里是sn-p:

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 并启用它。

现在您获得了服务帐号,您可以在项目中使用它。

【讨论】:

  • 在他们授权时您似乎有用户干预。我不要那个。有人告诉我我正在寻找的是使用服务帐户。我还没有这样做。如果你有例子欢迎提供
  • @yushauzumo 如果您需要的是服务帐户 sn-p 它的另一个故事,请查看我的 answer here 让我知道这是否与您想要实现的目标相似但使用 node.js .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-12
  • 2022-01-03
  • 1970-01-01
  • 2018-02-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多