如何在没有手动浏览器身份验证的情况下从 Meteor.js 应用程序对 GMail-api 进行 oauth (2) 身份验证?
Posted
技术标签:
【中文标题】如何在没有手动浏览器身份验证的情况下从 Meteor.js 应用程序对 GMail-api 进行 oauth (2) 身份验证?【英文标题】:How do I oauth (2) authenticate to GMail-api from a Meteor.js app without manual browser authentication? 【发布时间】: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 中使用哪些操作?你在读/写用户数据吗? 【参考方案1】:下面是简单的node.js
的工作sn-p
功能:
list labels send message get email您可以使用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);
);
如何创建服务帐号:
-
在Admin Console中创建项目
创建service account
转到管理控制台 > 安全 > 高级设置 > Manage API client access
在客户名称中输入您创建的服务帐户的完整电子邮件
在一个或多个 API 范围中输入 https://mail.google.com/ 并点击授权
返回Service accounts,选择您的帐户,启用 G Suite 域范围委派
创建服务帐户密钥(下载为 .json)
为您的项目激活 Gmail API。转到 API 和服务 > Dashboard,点击启用 API 和服务,搜索 Gmail 并启用它。
现在您获得了服务帐号,您可以在项目中使用它。
【讨论】:
在他们授权时您似乎有用户干预。我不要那个。有人告诉我我正在寻找的是使用服务帐户。我还没有这样做。如果你有例子欢迎提供 @yushauzumo 如果您需要的是服务帐户 sn-p 它的另一个故事,请查看我的 answer here 让我知道这是否与您想要实现的目标相似但使用node.js
.以上是关于如何在没有手动浏览器身份验证的情况下从 Meteor.js 应用程序对 GMail-api 进行 oauth (2) 身份验证?的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有客户端身份验证的情况下从服务器验证 Firebase 用户?
如何在未经身份验证的情况下从 Google Play 商店请求应用程序信息
为 Web API 实施 Azure AD 身份验证,可以在有和没有用户上下文的情况下从多个客户端调用?
是否可以在没有 OAuth2 身份验证对话框的情况下从 Google App-Engine (python) 连接和查询 BigQuery 表?