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(); ?>
网友回复