You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何为GOOGLE CLOUD JSON API生成Bearer令牌及GCS上传认证方案咨询

针对你提出的Google Cloud Storage(GCS)对象上传相关问题,我来逐一给你解答:

你当前使用的PHP curl上传代码如下:

<?php 
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, "https://www.googleapis.com/upload/storage/v1/b/Mybucket/o?uploadType=media"); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, "yourdata"); 
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 

$headers = array(); 
$headers[] = "Authorization:Bearer <TOKEN>"; 
$headers[] = "x-goog-project-id: xxxxxxxxxxx"; 
$headers[] = "x-goog-user-project: xxxxxxxxxxx"; 
$headers[] = "Content-Length: 8"; 
$headers[] = "Content-Type: image/jpeg"; 
$headers[] = "x-goog-acl: public-read-write"; 

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 

$result = curl_exec($ch); 
if (curl_errno($ch)) { 
    echo 'Error:' . curl_error($ch); 
} 
curl_close ($ch); 
?>
1. 无需Bearer令牌或其他替代认证的上传方法
  • 匿名上传(仅限配置公开权限的桶):如果你的存储桶已经设置了public-read-write的ACL(如你代码中指定的),并且桶的IAM策略允许匿名用户执行上传操作,那么可以直接移除Authorization请求头进行上传。但这种方式风险极高,生产环境绝对不推荐,因为任何知道桶地址的人都能随意上传内容。
  • 签名URL上传:这是更安全的无令牌上传方案。你可以在后端使用服务账号密钥生成一个带有过期时间的签名URL,前端或客户端直接使用这个URL就能上传对象,无需携带任何认证令牌。签名URL的权限、有效期都可以精确控制,既避免了令牌管理的麻烦,又保证了安全性。
  • 使用官方客户端库(自动处理认证):Google提供了官方的Cloud Storage PHP客户端库,你可以直接使用服务账号JSON密钥初始化客户端,库会自动处理认证流程(包括令牌的生成、缓存和刷新),不需要手动处理Bearer令牌。
2. 编程生成Bearer令牌(curl/PHP方式)

Bearer令牌属于OAuth2.0的访问令牌,针对服务账号场景,通常通过JWT(JSON Web Token)授权流程生成。以下是具体实现方式:

使用curl直接生成

你可以通过向Google的令牌端点发送请求,用服务账号JSON密钥生成JWT并交换访问令牌:

# 假设你的服务账号密钥文件名为service-account.json
curl -X POST "https://oauth2.googleapis.com/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \
  -d "assertion=$(python3 -c '
import jwt
import time
import json
with open("service-account.json") as f:
    data = json.load(f)
payload = {
    "iss": data["client_email"],
    "scope": "https://www.googleapis.com/auth/devstorage.read_write",
    "aud": "https://oauth2.googleapis.com/token",
    "exp": int(time.time()) + 3600,
    "iat": int(time.time())
}
print(jwt.encode(payload, data["private_key"], algorithm="RS256"))
')"

执行后会返回包含access_token的JSON响应,这个值就是你需要的Bearer令牌,有效期默认1小时。

使用PHP生成

你可以借助firebase/php-jwt库生成JWT,再通过HTTP请求交换令牌:
首先安装依赖:

composer require firebase/php-jwt guzzlehttp/guzzle

然后编写代码:

<?php
require 'vendor/autoload.php';

use Firebase\JWT\JWT;
use GuzzleHttp\Client;

// 加载服务账号密钥文件
$serviceAccount = json_decode(file_get_contents('service-account.json'), true);

$now = time();
// 构造JWT payload
$payload = [
    'iss' => $serviceAccount['client_email'], // 服务账号邮箱
    'scope' => 'https://www.googleapis.com/auth/devstorage.read_write', // 所需权限
    'aud' => 'https://oauth2.googleapis.com/token', // 令牌端点地址
    'exp' => $now + 3600, // 令牌有效期1小时
    'iat' => $now // 令牌签发时间
];

// 生成JWT
$jwt = JWT::encode($payload, $serviceAccount['private_key'], 'RS256');

// 发送请求获取access token
$client = new Client();
$response = $client->post('https://oauth2.googleapis.com/token', [
    'form_params' => [
        'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
        'assertion' => $jwt
    ]
]);

$tokenData = json_decode($response->getBody(), true);
$accessToken = $tokenData['access_token'];

// 现在可以将$accessToken用于你的上传请求
echo "Bearer Token: " . $accessToken;
?>

更简便的方式:使用官方PHP客户端库

如果你直接使用Google官方的Cloud Storage PHP客户端库,它会自动处理令牌的生成和刷新,无需手动实现上述流程:

<?php
require 'vendor/autoload.php';

use Google\Cloud\Storage\StorageClient;

// 使用服务账号密钥初始化客户端
$storage = new StorageClient([
    'keyFilePath' => 'service-account.json'
]);

// 获取目标存储桶
$bucket = $storage->bucket('Mybucket');
// 上传对象(这里以本地文件为例)
$bucket->upload(file_get_contents('your-file.jpg'), [
    'contentType' => 'image/jpeg',
    'acl' => 'public-read-write'
]);
?>

内容的提问来源于stack exchange,提问作者Eldhose Elias

火山引擎 最新活动