[GCP] OAuth 2.0 透過API驗證並獲取Token

google 一直是正方圓的最愛

從打開瀏覽器開始到雲端硬碟再到雲端平台

他們的文件是正方圓最看的懂的文件

像另外二家大頭就常常讓人抓的頭皮破,尤其是...平台名稱有W的那家

雖然OAuth2.0這件事也研究了一周以上,但至少有了結論,W那家則是常常走了一輪後,還是沒有結論。

這裡要展示使用php 從取得的service account 進行oauth身份驗證取得token,才能再利用其他google 提供的api進行存取

話說從頭,一開始正方圓就是要利用Google Stroage REST APIs對GCP上的Stroage進行存取

而從文件中可發現,他們需要一組Token,而這組Token是經過Google OAuth2.0 身份驗證過的Token

官方文件中提到可以透過OAuth 2.0 Playground 進行驗證取得Token,但正方圓是要從程式面進行存取

Token的時效都只有一個小時,基本上只能拿來測試,無法從程式面進行API存取用

所以這時就要出動GCP Service Account(服務帳戶)這個功能建立一組服務帳戶並且要指定權限可存取的項目(EX:Stroage),接著就是要向google OAuth 2.0 進行身份驗證了

從上圖可以看到建立了一個服務帳戶並設定好權限角色即可,因此會從GCP平台獲得一個JSON檔案

接著就是利用json檔中的「private_key」、「client_email」、「token_uri」三個資訊進行身份驗證取得一個小時有效的Token

文件中提到,google 他需要利用JWT的規則跟token_uri 資料交換獲得Token,而什麼是JWT,這裡有一篇文章寫的很好,可以參考一下。

主要有三要要素組成JWT,HEADER.PLYLOAD.SIGNATURE

三者都要用Base64url encoded 過,可參考下面內容:

function base64url_encode($data)
{
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

首先header 就照JWT的規則,會有alg與typ二個項目,google 要求的內容如下:

{"alg":"RS256","typ":"JWT"}

組好後再進行Base64url encode,header就完成了

接著就是重頭戲plyload,這裡的欄位就是可自定,這裡就照google的要求內容如下:

{
  "iss": your json [client_email],
  "scope": 參閱,
  "aud": your json [token_uri],
  "exp": 1328554385,//(time()+3600)
  "iat": 1328550785 //time()
}

組好後再進行Base64url encode,plyload就完成了

最後一個,也是最難的一個signature

簽名的部分需要透過openssl進行簽署,這裡用Generate 即可(openssl_sign)

原因可參考文件描述的Computing the signature部分

程式碼可參考下列內容:

主要就是要把前面的header與plyload用「.」相連 組成data,透過openssl_sign()函式產出signature,就是我們要的東西

function sign($data, your json [private_key])
{
    $signature = null;
    openssl_sign($data, $signature, your json [private_key], OPENSSL_ALGO_SHA256);
    return $signature;
}

所有的要素都組好了,透過token_url,就可向google 請求token回來了。

完整的程式

參考資料:

如何透過 Service Account 來取得 Google API 的 OAuth2 Token