“PHP 警告:fopen(/app/image.jpg):无法打开流:第 585 行 /app/vendor/google/cloud/src/Storage/StorageObject.php 中的权限被拒绝”
“PHP Warning: fopen(/app/image.jpg): failed to open stream: Permission denied in /app/vendor/google/cloud/src/Storage/StorageObject.php on line 585”
我在尝试使用 PHP 从 Google 云存储下载文件时遇到权限问题,方法是 API 从应用程序接收调用的方法。
为了确保安全,我创建了一个服务帐户,分配了管理员角色,并使用 .json 文件和该服务帐户的密钥在创建存储客户端时进行身份验证。然后在调用中我通过参数传递文件的数据(我已发布以防万一)和路线,但无论你尝试哪条路线总是留下相同的错误。
我的应用程序影响此方法的代码是:
<?php
use Silex\Application;
use Silex\Provider\TwigServiceProvider;
use Symfony\Component\HttpFoundation\Request;
use Google\Cloud\Storage\StorageClient;
// Crea la aplicacion de SILEX
$app = new Application();
//Descarga el archivo seleccionado de un siniestro.
$app->get('/download_archivos_siniestro_app', function () use ($app) {
$ARCH=$_REQUEST['Archivo'];
$destination=$_REQUEST['Ruta'];
require __DIR__ . '/vendor/autoload.php';
$path = "credenciales.json";
$keyFile = json_decode(file_get_contents($path), true);
$projectId = "mi_ID_del_proyecto";
$storage = new StorageClient($config = ['projectId' => $projectId, $keyFile]);
$bucketName = "mi_bucket";
$objectName = $ARCH;
$bucket = $storage->bucket($bucketName);
$object = $bucket->object($objectName);
$object->downloadToFile(__DIR__ .$destination);
$respuesta=array();
$respuesta['status']='0';
$respuesta['message']='Todo correcto!';
}
}
return $app->json($respuesta);
});
// Funcion para devolver la instancia del PDO
$app['database'] = function () use ($app) {
// Connect to CloudSQL from App Engine.
$dsn = getenv('MYSQL_DSN');
$user = getenv('MYSQL_USER');
$password = getenv('MYSQL_PASSWORD');
if (!isset($dsn, $user) || false === $password) {
throw new Exception('Set MYSQL_DSN, MYSQL_USER, and MYSQL_PASSWORD environment variables');
}
$db = new PDO($dsn, $user, $password);
return $db;
};
// Acepta peticiones JSON
$app->before(function (Request $request) {
if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
$data = json_decode($request->getContent(), true);
$request->request->replace(is_array($data) ? $data : array());
}
});
return $app;
?>
当我在调用中发送文件和目标参数时,我是这样做的:
https://midominiodegoogle.appspot.com/download_archivos_siniestro_app?Archivo=image.jpg&Ruta=/image.jpg
进行此调用后,我在控制台日志中收到以下错误:
"PHP message: PHP Warning: fopen(/app/image.jpg): failed to open stream: Permission denied in /app/vendor/google/cloud/src/Storage/StorageObject.php on line 585"
其他 API 方法没有问题,错误仅仅是因为无法将您尝试下载的文件放在任何指定的文件夹中。
在此先感谢您的帮助。
对于服务帐户 Storage Admin
角色将不起作用,您需要一个名为 Storage Object Admin
的角色。我知道这很混乱。
额外提示:最佳做法是永远不要向您的服务帐户授予管理员权限。您应该使用 objectCreator
或 objectViewer
,具体取决于您是要创建还是查看存储桶中的文件
在 App Engine 中,为了存储文件,您应该使用 Cloud Storage。引用 documentation:
If your PHP 7 app needs to read and write files during runtime, or serve files such as movies, images or other static content, we recommend you use a Cloud Storage bucket
但是,如果出于特定原因您的需要要求文件看起来就像在本地磁盘中一样,您应该能够将其存储在 /tmp
目录中。您可以在 Reading and Writing Temporary Files docs
中找到更多信息以及代码片段
我在尝试使用 PHP 从 Google 云存储下载文件时遇到权限问题,方法是 API 从应用程序接收调用的方法。
为了确保安全,我创建了一个服务帐户,分配了管理员角色,并使用 .json 文件和该服务帐户的密钥在创建存储客户端时进行身份验证。然后在调用中我通过参数传递文件的数据(我已发布以防万一)和路线,但无论你尝试哪条路线总是留下相同的错误。
我的应用程序影响此方法的代码是:
<?php
use Silex\Application;
use Silex\Provider\TwigServiceProvider;
use Symfony\Component\HttpFoundation\Request;
use Google\Cloud\Storage\StorageClient;
// Crea la aplicacion de SILEX
$app = new Application();
//Descarga el archivo seleccionado de un siniestro.
$app->get('/download_archivos_siniestro_app', function () use ($app) {
$ARCH=$_REQUEST['Archivo'];
$destination=$_REQUEST['Ruta'];
require __DIR__ . '/vendor/autoload.php';
$path = "credenciales.json";
$keyFile = json_decode(file_get_contents($path), true);
$projectId = "mi_ID_del_proyecto";
$storage = new StorageClient($config = ['projectId' => $projectId, $keyFile]);
$bucketName = "mi_bucket";
$objectName = $ARCH;
$bucket = $storage->bucket($bucketName);
$object = $bucket->object($objectName);
$object->downloadToFile(__DIR__ .$destination);
$respuesta=array();
$respuesta['status']='0';
$respuesta['message']='Todo correcto!';
}
}
return $app->json($respuesta);
});
// Funcion para devolver la instancia del PDO
$app['database'] = function () use ($app) {
// Connect to CloudSQL from App Engine.
$dsn = getenv('MYSQL_DSN');
$user = getenv('MYSQL_USER');
$password = getenv('MYSQL_PASSWORD');
if (!isset($dsn, $user) || false === $password) {
throw new Exception('Set MYSQL_DSN, MYSQL_USER, and MYSQL_PASSWORD environment variables');
}
$db = new PDO($dsn, $user, $password);
return $db;
};
// Acepta peticiones JSON
$app->before(function (Request $request) {
if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
$data = json_decode($request->getContent(), true);
$request->request->replace(is_array($data) ? $data : array());
}
});
return $app;
?>
当我在调用中发送文件和目标参数时,我是这样做的:
https://midominiodegoogle.appspot.com/download_archivos_siniestro_app?Archivo=image.jpg&Ruta=/image.jpg
进行此调用后,我在控制台日志中收到以下错误:
"PHP message: PHP Warning: fopen(/app/image.jpg): failed to open stream: Permission denied in /app/vendor/google/cloud/src/Storage/StorageObject.php on line 585"
其他 API 方法没有问题,错误仅仅是因为无法将您尝试下载的文件放在任何指定的文件夹中。
在此先感谢您的帮助。
对于服务帐户 Storage Admin
角色将不起作用,您需要一个名为 Storage Object Admin
的角色。我知道这很混乱。
额外提示:最佳做法是永远不要向您的服务帐户授予管理员权限。您应该使用 objectCreator
或 objectViewer
,具体取决于您是要创建还是查看存储桶中的文件
在 App Engine 中,为了存储文件,您应该使用 Cloud Storage。引用 documentation:
If your PHP 7 app needs to read and write files during runtime, or serve files such as movies, images or other static content, we recommend you use a Cloud Storage bucket
但是,如果出于特定原因您的需要要求文件看起来就像在本地磁盘中一样,您应该能够将其存储在 /tmp
目录中。您可以在 Reading and Writing Temporary Files docs