我如何使用node.js和PHP来请求谷歌浏览器中的客户端js的大查询authentication

在放弃对其他数据库的大量查询之前,我希望有人能够指出我的需求。 我正在Google计算实例上创build一个应用程序,用于访问存储在大查询中的数据。 这是我的理想用户体验:

  1. 用户使用他们的浏览器来select与他们想要的数据相关的选项,

  2. 一旦完成,用户提交一个表格,并查询相关的bq表格,并将结果发回给用户。

我有一切正常工作,但只有当我用我的谷歌帐户login。 当然,未经身份validation的用户不能访问数据集。 我尝试了一个解决方法,指导用户如何创build一个免费的开发者帐户,以便他们可以访问该网站,但这似乎是非技术用户的严重障碍。 我明白为什么客户端查询不能访问我的大查询帐户,我意识到允许客户端查询意味着我负责他们。 我没关系。 我也理解可用的各种authentication方式,并有一个工作的服务帐户,以及谷歌的官方node.jsauthentication包。 我可以从命令行进行身份validation。 我想要的是一个简单的方法,我可以让用户通过服务器端脚本透明地进行身份validation。 我设想一个php调用命令行运行一个node.js文件,该文件生成一个令牌文件,然后可以由用户的浏览器读取,以便我现有的应用程序代码可以使用,而无需重大重构。

例如,在index.php中:

<?php exec("node myAuth.js"); $my_token = file_get_contents("myToken.json"); ?> 

也在index.php中:

 var myToken = '<?php echo $my_token; ?>'; 

在myAuth.js(几乎逐字从https://github.com/google/google-auth-library-nodejs )

 var GoogleAuth = require('google-auth-library'); var _ = require('lodash'); // Get the environment configured authorization (new GoogleAuth).getApplicationDefault(function(err, authClient) { if (err === null) { // Inject scopes if they have not been injected by the environment if (authClient.createScopedRequired && authClient.createScopedRequired()) { var scopes = [ 'https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/compute' ]; authClient = authClient.createScoped(scopes); } // Fetch the access token var optionalUri = null; // optionally specify the URI being authorized var reqHeaders = {}; authClient.getRequestMetadata(optionalUri, function(err, headers) { if (err === null) { // Use authorization headers reqHeaders = _.merge(reqHeaders, headers); console.log(headers); } 

我知道很less的PHP,并不熟悉服务器端的JS。 我在这里放在一起是从阅读StackOverflow答案和谷歌文档…但我找不到有关谷歌客户端API的坚果和螺栓的文档。 具体来说,如果我通过官方的node.js库产生一个authentication令牌,我可以 – 以及如何 – 在客户端使用该令牌调用gapi.auth API? 我宁愿不必安装socket.io或第三方库。 我是一个新的开发人员,但渴望学习和阅读,所以如果任何人有机会获得真实的文档(除了谷歌自己提供的通告,模糊和稀疏的文档),我会非常感激。 一个完整的任何forms的例子将是惊人的。 同样,重点是在服务器端进行尽可能less的处理,因为我已经完成了完整的客户端逻辑。 理想情况下,所有的服务器都是给我一个令牌。

为logging该网站的问题是app.socioscapes.com 。 谢谢。

如果其他人想这样做,这是我如何实现它。

(但是,在你做这件事之前,请记住你将对你的用户启动的所有查询负责,你应该把这个和caching系统一起使用,超出了BQ本身的实现。)

概述:您需要设置服务帐户,以便服务器上的php脚本可以安全地从Google中检索OAuth2令牌。 然后,而不是启动一个常规gapi.auth.authorizestream程,您将使用gapi.auth.setToken插入您的服务标记。

第1步:使用PHP检索令牌。 这个代码几乎是逐字从用户Pentium10的答案在这里 。

  <?php session_start(); define('PROJECT_ID', 'REPLACE THIS'); define('DATASET_ID', 'REPLACE THIS'); define('API_KEY', 'REPLACE THIS'); $client_id = 'REPLACE THIS'; $service_account_name = 'REPLACE THIS'; $key_file_location = '.private/privatekey-bigquery.p12'; $service_token_file_location = 'uploads/bigquery_current_service_token.json'; require_once './php_modules/google-api-php-client/src/Google/autoload.php'; // or wherever autoload.php is located $client = new Google_Client(); $client->setApplicationName("Client_Library_Examples"); if (!is_file($service_token_file_location)) { if (!is_writable($service_token_file_location)) { @chmod($service_token_file_location, 0777); if (!is_writable($service_token_file_location)) { die('Service token file is not writable: ' . $service_token_file_location); } } file_put_contents($service_token_file_location, ''); } else { if (!is_writable($service_token_file_location)) { @chmod($service_token_file_location, 0777); if (!is_writable($service_token_file_location)) { die('Service token file is not writable: ' . $service_token_file_location); } } } $service_token = @file_get_contents($service_token_file_location); if (!empty($service_token)) { $client->setAccessToken($service_token); } if (!file_exists($key_file_location)) { die('Key file is missing: ' . $key_file_location); } $key = file_get_contents($key_file_location); $cred = new Google_Auth_AssertionCredentials( $service_account_name, array( 'https://www.googleapis.com/auth/bigquery', ), $key ); $client->setAssertionCredentials($cred); if ($client->getAuth()->isAccessTokenExpired()) { $client->getAuth()->refreshTokenWithAssertion($cred); } $service_token = $client->getAccessToken(); file_put_contents($service_token_file_location, $service_token); ?> 

第2步:在JS中使用令牌。

在步骤1之后只需包含以下代码:

 <script> const SERVICETOKEN = <?php echo $service_token ?>; gapi.auth.setToken({ access_token: config.auth.access_token }); gapi.client.load('bigquery', 'v2', function(r) { // gapi.client.bigquery.jobs.query({YOUR CONFIG}); // etc etc }); </script>