“ PHP警告:fopen(/app/image.jpg):打开流失败:/app/vendor/google/cloud/src/Storage/StorageObject.php在第585行的权限被拒绝”

问题描述 投票:0回答:2

我有一个权限问题,尝试使用PHP从接收到应用程序调用的API方法中使用PHP从Google Cloud Storage下载文件。

[为确保安全,我创建了一个服务帐户,分配了管理员角色,并在创建Storage Client时使用了带有该服务帐户密钥的.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方法工作正常,错误仅是由于无法将您要下载的文件放在任何指定的文件夹中。

提前感谢您的帮助。

php api google-cloud-platform google-cloud-storage fopen
2个回答
0
投票

对于服务帐户Storage Admin角色将不起作用,您需要一个名为Storage Object Admin的角色。我知道这很令人困惑。

奖金提示:最佳实践是,永远不要授予服务帐户的管理员权限。您应根据要创建还是查看存储桶中的文件使用objectCreatorobjectViewer

GCP Role selector screen


0
投票

在App Engine中,为了存储文件,您应该使用Cloud Storage。引用documentation

如果您的PHP 7应用程序需要在运行时读取和写入文件,或提供电影,图像或其他静态内容之类的文件,我们建议您使用Cloud Storage存储桶

但是,由于特殊原因,如果您的需要将文件显示在本地磁盘中,则应将其存储在/tmp目录中。您可以在Reading and Writing Temporary Files docs

中找到更多信息以及代码段。
© www.soinside.com 2019 - 2024. All rights reserved.