Google 云客户端库和用户身份验证
Google cloud client libraries and user authentication
我正在为 Google Cloud Platform 开发我的第一个应用程序。
特别是,我使用 Node.js 作为基础框架。 Google 本身提供 Node.js client libraries 与他们的服务交互。
例如,此代码能够在 Cloud Storage 中创建一个新存储桶:
var storage = require('@google-cloud/storage')();
var bucket = storage.bucket('albums');
bucket.create(function(err, bucket, apiResponse) {
if (!err) {
// The bucket was created successfully.
}
});
//-
// If the callback is omitted, we'll return a Promise.
//-
bucket.create().then(function(data) {
var bucket = data[0];
var apiResponse = data[1];
});
但是,如果我在 Google 应用程序引擎上部署此代码,则上述操作是使用服务帐户(我想至少)完成的,而不是作为最终用户,即使在 OAuth 身份验证之后,因此忽略了现有的 IAM 策略。
我怎样才能避免这个问题,并为我的请求使用以用户为中心的流程?我可以使用身份感知代理吗?如果是,如何?
更新
为了让我的问题更容易理解:
考虑这段代码:
router.get('/test2', oauth2.required, (req, res, next) => {
const Storage = require('@google-cloud/storage');
// Creates a client
const storage = new Storage();
// Lists all buckets in the current project
storage
.getBuckets()
.then(results => {
const buckets = results[0];
console.log('Buckets:');
buckets.forEach(bucket => {
console.log(bucket.name);
});
res.send("There are " + buckets.length + " buckets.");
})
.catch(err => {
res.send(err);
});
});
如果给定用户已经通过 OAuth2 登录,则可以调用此路由。
我想调用传递 OAuth accessToken 的 getBuckets()
方法来模拟用户本身执行此操作。
这样,该操作就无法跳过 GCP 中针对当前登录的给定用户的 IAM 规则。
我试了一下:
const storage = new Storage({
auth: {
'bearer': req.user.accessToken
}});
但是不行。该应用程序仍然使用我的默认帐户。
您有两种选择来确保您的请求被允许:
向您的服务帐户授予对存储桶 and/or 对象的必要权限。如果您控制数据,则此方法有效,但如果您的应用程序必须使用 buckets/objects 用户控件运行,则此方法无效。
执行 "three legged Oauth" 流程以获得代表用户拨打电话的权限。不幸的是,您调用的客户端库不支持此功能。我不知道你从哪里得到 auth:{'bearer':...}
,但即使它确实有效,你传递的令牌也不会有访问存储桶所需的范围。
This autogenerated library 确实支持 three-legged 身份验证。你会像这样使用它:
var google = require('googleapis');
var OAuth2 = google.auth.OAuth2;
var oauth2Client = new OAuth2(
YOUR_CLIENT_ID,
YOUR_CLIENT_SECRET,
YOUR_REDIRECT_URL
);
function handle_requests_to_redirect_url() {
// extract code query string parameter
token = await oauth2Client.getToken(code);
// Save token
}
if (no_known_auth_token_for_user()) {
// redirect user to
oauth2Client.generateAuthUrl({access_type:'offline', scope: ['https://www.googleapis.com/auth/devstorage.read_write']});
// after clicking OK, user is redirected to YOUR_REDIRECT_URL
}
var token = get_saved_token_for_this_user();
oauth2Client.setCredentials(token);
var storage = google.storage({version: 'v1', auth: oauth2Client});
storage.buckets.list(function (e,res) {
console.log(res);
});
我正在为 Google Cloud Platform 开发我的第一个应用程序。
特别是,我使用 Node.js 作为基础框架。 Google 本身提供 Node.js client libraries 与他们的服务交互。
例如,此代码能够在 Cloud Storage 中创建一个新存储桶:
var storage = require('@google-cloud/storage')();
var bucket = storage.bucket('albums');
bucket.create(function(err, bucket, apiResponse) {
if (!err) {
// The bucket was created successfully.
}
});
//-
// If the callback is omitted, we'll return a Promise.
//-
bucket.create().then(function(data) {
var bucket = data[0];
var apiResponse = data[1];
});
但是,如果我在 Google 应用程序引擎上部署此代码,则上述操作是使用服务帐户(我想至少)完成的,而不是作为最终用户,即使在 OAuth 身份验证之后,因此忽略了现有的 IAM 策略。
我怎样才能避免这个问题,并为我的请求使用以用户为中心的流程?我可以使用身份感知代理吗?如果是,如何?
更新
为了让我的问题更容易理解:
考虑这段代码:
router.get('/test2', oauth2.required, (req, res, next) => {
const Storage = require('@google-cloud/storage');
// Creates a client
const storage = new Storage();
// Lists all buckets in the current project
storage
.getBuckets()
.then(results => {
const buckets = results[0];
console.log('Buckets:');
buckets.forEach(bucket => {
console.log(bucket.name);
});
res.send("There are " + buckets.length + " buckets.");
})
.catch(err => {
res.send(err);
});
});
如果给定用户已经通过 OAuth2 登录,则可以调用此路由。
我想调用传递 OAuth accessToken 的 getBuckets()
方法来模拟用户本身执行此操作。
这样,该操作就无法跳过 GCP 中针对当前登录的给定用户的 IAM 规则。
我试了一下:
const storage = new Storage({
auth: {
'bearer': req.user.accessToken
}});
但是不行。该应用程序仍然使用我的默认帐户。
您有两种选择来确保您的请求被允许:
向您的服务帐户授予对存储桶 and/or 对象的必要权限。如果您控制数据,则此方法有效,但如果您的应用程序必须使用 buckets/objects 用户控件运行,则此方法无效。
执行 "three legged Oauth" 流程以获得代表用户拨打电话的权限。不幸的是,您调用的客户端库不支持此功能。我不知道你从哪里得到
auth:{'bearer':...}
,但即使它确实有效,你传递的令牌也不会有访问存储桶所需的范围。This autogenerated library 确实支持 three-legged 身份验证。你会像这样使用它:
var google = require('googleapis'); var OAuth2 = google.auth.OAuth2; var oauth2Client = new OAuth2( YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REDIRECT_URL ); function handle_requests_to_redirect_url() { // extract code query string parameter token = await oauth2Client.getToken(code); // Save token } if (no_known_auth_token_for_user()) { // redirect user to oauth2Client.generateAuthUrl({access_type:'offline', scope: ['https://www.googleapis.com/auth/devstorage.read_write']}); // after clicking OK, user is redirected to YOUR_REDIRECT_URL } var token = get_saved_token_for_this_user(); oauth2Client.setCredentials(token); var storage = google.storage({version: 'v1', auth: oauth2Client}); storage.buckets.list(function (e,res) { console.log(res); });