我正在用后端的PHP创建一个在线代码编辑器,用户可以在其中创建可以包括图像的代码项目.我在谷歌上创建了一个服务账户,并获得了一个私钥.我想使用PHP将照片上传到Google云存储API,使用cURL将图像存储在云中并检索它们; 但是..

  • 我听说过谷歌API PHP客户端库,但它使用composer ,我的网络主机不允许composer 或shell 访问,而且库太大,我的网络主机的存储容量非常有限(这就是为什么我首先考虑谷歌云存储来存储上传的照片).

  • 我知道访问令牌,并使用访问令牌成功地使用PHP将图像上传到存储,但这些令牌是临时的,只能持续一个小时,即使是刷新令牌也是临时的. 所以. 我想要一个永久的方式来调用"原生PHP"的API,并上传到谷歌云.我创建了一个服务帐号并获取了私钥,但无法成功上传到API.到目前为止,我的代码如下:

         // I  previously initialized the variables $bucketName , $projectId , and $jsonKey
    
         function is_valid_image($file) {
          $allowed_types = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'];
    
          if (!in_array($file['type'], $allowed_types)) {
           return false;
          }
    
         return true;
         }
    
    
         if ($_SERVER['REQUEST_METHOD'] === 'POST') {
         if (isset($_FILES['image'])) {  
         if (is_valid_image($_FILES['image'])) {
    
             $localFilePath = $_FILES['image']['tmp_name'];
             $objectName = $_FILES['image']['name'];
             $fileContent = base64_encode(file_get_contents($localFilePath));
             $uploadUrl = "https://storage.googleapis.com/upload/storage/v1/b/{$bucketName}/o?uploadType=media&name={$objectName}";
             $serviceAccountKey = json_decode($jsonKey);
             $authHeader = "Authorization: Bearer " . $serviceAccountKey['private_key'];
    
             $ch = curl_init($uploadUrl);
             curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
             curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['name' => $objectName, 'content' => $fileContent]));
             curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
             curl_setopt($ch, CURLOPT_HTTPHEADER, [
                 'Content-Type: application/json',
                 $authHeader,
             ]);
    
             $response = curl_exec($ch);
             echo $response;
             curl_close($ch);
    
             require "db_update.php";
    
         } else {
             echo 'Invalid file type. Please upload a valid image (JPEG, JPG, PNG, GIF).';
         }
     } else {
         echo 'Error uploading picture. Please try again.';
     }
    

但它不工作,我得到这样的回应:

{"错误":{"code":401,"Message":"无效凭据","Errors":[{"Message":"无效凭据","域":"全局","原因":"authError","LocationType":"Header","LocationType":"AuthError","LocationType":"授权"}}

我做错了什么?当我使用临时令牌时,它工作得很好,如何在不使用Google存储API库的情况下正确使用它?

推荐答案

Google Cloud Storage API需要一个用于身份验证的访问令牌,而不是直接使用私钥(而且,一旦您发送了私钥,它就不再是真正的私有密钥,我会轮换它).

此外,对于uploadType=media,您的有效负载应该是文件的二进制数据,而不是JSON有效负载中的Base64编码字符串.

Php相关问答推荐

在Laravel中,如果我用session—put()存储一些信息,客户端浏览器是否可以使用这些信息?>

WooCommerce中仅在单一产品和产品档案页面中将小数设置为大写

显示WooCommerce当前产品类别或标签的短代码

WooCommerce在store 页面上显示兼容多语言的产品属性

在WooCommerce管理订单列表中显示项目总权重

无法在WooCommerce中发送客户笔记邮箱通知

是否重新排序多维数组元素以将所有子数组中的子数组移动到元素列表的底部?

免费送货柜台,考虑到折扣码

Laravel路由到控制器传输变量解决方案需要

WordPress:今天的计数';修改和发布的帖子

如何批量处理消息总线中的消息

PHP 中使用 JSON 的自定义会话处理程序会因错误而 destruct 会话

获取 Shopware 6 集合元素的值,PHP

使用 PHP 的 OAuth 2.0 MAC

在WooCommerce中显示 checkout 的高级自定义字段(Advanced Custom Fields)并保存其值

php var_dump(1) 返回字符串(4)

如何更改或管理Carbon时区,使其不会来回移动时钟

PHP/Laravel 中的自定义时区

为什么 ECDSA 384 签名验证在 GO 中失败,但在 PHP 中却没有?

一个php应用程序可以实例化多个RNG吗