【发布时间】:2019-08-03 13:38:36
【问题描述】:
我正在尝试对用户进行身份验证以访问用户 Gsuite 中的各种范围。我可以在本地运行代码,但似乎无法将其作为云功能接受。
我尝试过使用 firebase 和 gcloud 进行部署。我检查了我的 eslint 设置。
此代码来自https://github.com/googleapis/google-api-nodejs-client/blob/master/README.md#oauth2-client
'use strict';
const fs = require('fs');
const path = require('path');
const http = require('http');
const url = require('url');
const opn = require('open');
const destroyer = require('server-destroy');
const {google} = require('googleapis');
/**
* To use OAuth2 authentication, we need access to a a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI. To get these credentials for your application, visit https://console.cloud.google.com/apis/credentials.
*/
const keyPath = path.join(__dirname, 'credentials.json');
let keys = {redirect_uris: ['']};
if (fs.existsSync(keyPath)) {
keys = require(keyPath).web;
}
/**
* Create a new OAuth2 client with the configured keys.
*/
const oauth2Client = new google.auth.OAuth2(
keys.client_id,
keys.client_secret,
`http://localhost:3000/oauth2callback`
);
/**
* This is one of the many ways you can configure googleapis to use authentication credentials. In this method, we're setting a global reference for all APIs. Any other API you use here, like google.drive('v3'), will now use this auth client. You can also override the auth client at the service and method call levels.
*/
google.options({auth: oauth2Client});
const scopes = ['https://www.googleapis.com/auth/documents'];
/**
* Open an http server to accept the oauth callback. In this simple example, the only request to our webserver is to /callback?code=<code>
*/
async function authenticate(){
// grab the url that will be used for authorization
const authorizeUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: scopes
});
const server = http.createServer(async (req, res) => {
try {
if (req.url.indexOf('/oauth2callback') > -1) {
const qs = new url.URL(req.url, 'http://localhost:3000').searchParams;
res.end('Authentication successful! Please return to the console.');
server.destroy();
const {tokens} = await oauth2Client.getToken(qs.get('code'));
oauth2Client.credentials = tokens; // eslint-disable-line require-atomic-updates
resolve(oauth2Client);
}
} catch (e) {
reject(e);
}
})
.listen(3000, () => {
// open the browser to the authorize url to start the workflow
opn(authorizeUrl, {wait: false}).then(cp => cp.unref())
.catch(
error => {
console.log(error);
});
});
destroyer(server)
.then(client => runSample(client)).catch(
error => {
console.log(error);
});
};
module.exports.authenticate=authenticate;
async function runSample(client) {
// retrieve user profile
console.log(client);
const docs = google.docs({
version: 'v1',
auth: client
});
const createResponse = await docs.documents.create({
requestBody: {
title: 'Your new document!',
},
});
}
我希望它作为云功能加载到 firebase 或 gcloud。 然而: Firebase 返回“部署完成”,但它从未在函数中显示。 gcloud 返回“SyntaxError: Unexpected token function”,其中包含“async function authenticate(){”中指示的单词 function
我是 node.js 的新手,可能会遗漏一些对其他人来说非常明显的东西。
【问题讨论】:
-
您永远不会让用户凭据(客户端 ID/客户端密码)在 Cloud Functions 中工作(即身份验证和创建凭据)。 OAuth 需要网络浏览器和人工。 Cloud Functions 中都不存在。请改用服务帐户。
-
我希望通过 http 触发器将 oAuth 流程与云功能结合,重定向以获得批准并返回令牌代码以调用 API。我对服务帐户的理解是对他们可以访问的范围的限制。我弄错了吗?
-
如果您担心范围,请将它们放在您的问题中。要使用 Cloud Functions 指定
redirect_uri,您需要知道/管理域名。您不能使用 Cloud Functions。 Cloud Run 或 App Engine 是更好的选择。 -
我很关心如何知道这可以并且应该如何工作。我习惯了 Apps 脚本。这是我第一次尝试使用 Node.js,我想指出任何可以提供帮助的资源。我的目标是与对话流链接。
-
第一步是了解 OAuth 的工作原理。这是我写的一篇使用 curl 的文章:jhanley.com/google-oauth-2-0-testing-with-curl
标签: node.js google-cloud-functions google-oauth google-api-nodejs-client