gcloud access-token这个值谷歌cloud官方是通过gcloud 的客户端命令行获取的,需要下载到本地运行后获取
当然也有人根据这套协议写出了不需要命令行的代码,模拟了命令行的执行:
我们以cloudflare的worker为例,其他的编程语言可以通过ai更换:
// 配置变量
const PROJECT_ID = '';
const CLIENT_EMAIL = '';
const PRIVATE_KEY ="";
addEventListener("fetch", (event) => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
const [token, err] = await exchangeJwtForAccessToken(signedJWT)
if (token === null) {
console.log(`Invalid jwt token: ${err}`)
return createErrorResponse(500, "api_error", "invalid authentication credentials");
}
}
function createErrorResponse(status, errorType, message) {
const errorObject = { type: "error", error: { type: errorType, message: message } };
return new Response(JSON.stringify(errorObject), {
status: status,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
});
}
async function createSignedJWT(email, pkey) {
pkey = pkey.replace(/-----BEGIN PRIVATE KEY-----|-----END PRIVATE KEY-----|\r|\n|\\n/g, "");
let cryptoKey = await crypto.subtle.importKey(
"pkcs8",
str2ab(atob(pkey)),
{
name: "RSASSA-PKCS1-v1_5",
hash: { name: "SHA-256" },
},
false,
["sign"]
);
const authUrl = "https://www.googleapis.com/oauth2/v4/token";
const issued = Math.floor(Date.now() / 1000);
const expires = issued + 600;
const header = {
alg: "RS256",
typ: "JWT",
};
const payload = {
iss: email,
aud: authUrl,
iat: issued,
exp: expires,
scope: "https://www.googleapis.com/auth/cloud-platform",
};
const encodedHeader = urlSafeBase64Encode(JSON.stringify(header));
const encodedPayload = urlSafeBase64Encode(JSON.stringify(payload));
const unsignedToken = `${encodedHeader}.${encodedPayload}`;
const signature = await crypto.subtle.sign(
"RSASSA-PKCS1-v1_5",
cryptoKey,
str2ab(unsignedToken)
);
const encodedSignature = urlSafeBase64Encode(signature);
return `${unsignedToken}.${encodedSignature}`;
}
async function exchangeJwtForAccessToken(signed_jwt) {
const auth_url = "https://www.googleapis.com/oauth2/v4/token";
const params = {
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
assertion: signed_jwt,
};
const r = await fetch(auth_url, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: Object.entries(params)
.map(([k, v]) => k + "=" + v)
.join("&"),
}).then((res) => res.json());
if (r.access_token) {
return [r.access_token, ""];
}
return [null, JSON.stringify(r)];
}
function str2ab(str) {
const buffer = new ArrayBuffer(str.length);
let bufferView = new Uint8Array(buffer);
for (let i = 0; i < str.length; i++) {
bufferView[i] = str.charCodeAt(i);
}
return buffer;
}
function urlSafeBase64Encode(data) {
let base64 = typeof data === "string" ? btoa(encodeURIComponent(data).replace(/%([0-9A-F]{2})/g, (match, p1) => String.fromCharCode(parseInt("0x" + p1)))) : btoa(String.fromCharCode(...new Uint8Array(data)));
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
}php
<?php
// 配置变量
$PROJECT_ID = '';
$CLIENT_EMAIL = '';
$PRIVATE_KEY = "";
// 主函数
function main() {
global $CLIENT_EMAIL, $PRIVATE_KEY;
$signedJWT = createSignedJWT($CLIENT_EMAIL, $PRIVATE_KEY);
list($token, $err) = exchangeJwtForAccessToken($signedJWT);
if ($token === null) {
error_log("Invalid jwt token: $err");
return createErrorResponse(500, "api_error", "invalid authentication credentials");
}
// 这里可以继续处理 $token
}
function createErrorResponse($status, $errorType, $message) {
$errorObject = ['type' => 'error', 'error' => ['type' => $errorType, 'message' => $message]];
http_response_code($status);
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
echo json_encode($errorObject);
}
function createSignedJWT($email, $pkey) {
$pkey = preg_replace('/-----BEGIN PRIVATE KEY-----|-----END PRIVATE KEY-----|\r|\n|\\n/', '', $pkey);
$privateKey = openssl_pkey_get_private(base64_decode($pkey));
if (!$privateKey) {
throw new Exception("Failed to load private key");
}
$authUrl = "https://www.googleapis.com/oauth2/v4/token";
$issued = time();
$expires = $issued + 600;
$header = [
'alg' => 'RS256',
'typ' => 'JWT'
];
$payload = [
'iss' => $email,
'aud' => $authUrl,
'iat' => $issued,
'exp' => $expires,
'scope' => 'https://www.googleapis.com/auth/cloud-platform'
];
$encodedHeader = urlSafeBase64Encode(json_encode($header));
$encodedPayload = urlSafeBase64Encode(json_encode($payload));
$unsignedToken = "$encodedHeader.$encodedPayload";
openssl_sign($unsignedToken, $signature, $privateKey, OPENSSL_ALGO_SHA256);
$encodedSignature = urlSafeBase64Encode($signature);
return "$unsignedToken.$encodedSignature";
}
function exchangeJwtForAccessToken($signed_jwt) {
$auth_url = "https://www.googleapis.com/oauth2/v4/token";
$params = [
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $signed_jwt
];
$options = [
'http' => [
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($params)
]
];
$context = stream_context_create($options);
$result = file_get_contents($auth_url, false, $context);
if ($result === FALSE) {
return [null, "Failed to get access token"];
}
$r = json_decode($result, true);
if (isset($r['access_token'])) {
return [$r['access_token'], ""];
}
return [null, json_encode($r)];
}
function urlSafeBase64Encode($data) {
$base64 = base64_encode($data);
return str_replace(['+', '/', '='], ['-', '_', ''], $base64);
}
// 调用主函数
main();
?> 网友回复


