Google自Search推出後,相繼推出Gmail、Docs等服務,屢屢都以壓倒性的創新與技術驚訝資訊技術領域。從軟體服務(Software as a Service)出發,後來Google開始Release許許多多的API(Application Programming Interface)讓開發者可以免去重頭開發的工作,只需要申請直接呼叫使用,讓許多開發者在Web 2.0的世代開創了不少的應用服務。而步入雲端的世代,Google更堅持一貫的理念,所有的應用服務,上自SaaS的應用,下至IaaS的操作,所有的一切均基於讓使用者可以透過API操作為主,進一步延伸許多可直接呼叫的Client Library,讓開發者更容易跟Google APIs銜接。

而在技術層面,Google從早期提供App Engine使用的SDK到Google Data API,漸漸得演變成以RESTful為主的API模式,近期,RESTful API的模式幾乎統一了整個Google APIs的呼叫,甚至新一代的雲端服務,都以RESTful API為優先考量。目前,Google在釋出一個服務時,通常都已經準備好對應的RESTful API以及主要的一些開發語言的SDK。

管理面,Google早期的API以App Engine的Portal來管理各種API的使用狀態、權限以及Quota Limit,而在近期,Google Cloud Platform(GCP)推出後,已經將API的管理介面整合到Cloud Console(https://console.developers.google.com/)中,透過與Cloud整合的介面,似乎跟大家宣告,Google APIs已經是Cloud的一部分!

使用上,開發者必須先具備Google Cloud Platform的專案,在專案的”APIs & auth > APIs”分項中,可以看到關於該API的使用狀態與Quota設定,開發者可以在這邊清楚的瞭解目前使用該API的狀態。

而考慮資源分配與計費的情況下,API會有使用的頻率限制,Google所限制的方式一般分成每個user在一定時間內的呼叫次數限制(ex: request/second/user),或是每固定時間的呼叫次數限制(ex: Daily limit),在這邊API console也適當的地方提供了Quota的資訊,必要時候,透過Quota的申請介面,可以修改您程式使用到該API的使用量限制。

另外,服務的Quota與API的Limit通常需要把他分開搞清楚,以Compute Engine服務而言,可以開幾個core的主機、可使用的硬碟總size、靜態IP數量... 這些資訊會在Compute Engine服務下的Quota page來做設定,但是Compute Engine API則是在API console來做設定,以該API呼叫的頻率與次數做限制,限制的項面也有所不同。

整個API的管理部分,Google以自助平台的方式讓使用者盡量以最簡單的方式可以在線上操作完成,而所有的限制、擴充申請、使用狀態,也漸漸完善到這個平台...

Node.js在使用Google APIs的優點

談到Node.js,間單的說他是基於Google V8 engine上執行的JavaScript(JS)相容語法的Server端程式,與JS一樣,他具備Non-Block的特性,另外也因為V8 engine優異的效能,以及NPM(Node.js Package Management)的套件管理方式。讓Node.js在Web開發上廣受好評。再者,Node.js以相容ES6的特性,使得前端開發者能快速的加入中後端開發者的陣營,因此讓許多網頁開發人員玩一次就愛不釋手。

在這邊我們引用Node.js官方網站首頁所展示的Sample Code,我們可以看到Node.js所提供的模組能夠快速的以5行code建置一個羽量級的Web Server,不只如此,他還可以提供高速的回覆速度(response time)。

與多數喜愛Node.js的人不同,筆者身為一位後端比例偏重的工程師,一開始接觸Node.js時,就被他可以快速處理網路呼叫與回應的特性吸引,而且在Node.js中,開發者會更直接的接觸到HTTP層的各項屬性,例如headers、method、payload等等,這些參數在物件導向的程式語言的相關套件中通常被封裝在不同的流程或是設定裡,雖然具備許多結構化上的好處,但也讓初學者不容易進一步了解整個網際網路封包傳遞的精髓。

簡單的接軌API

從Node.js跨入Google API之前,我們需要先了解Google目前正朝向全面採用Oauth2的方式來認證他所提供的API服務,因此開發者需要首先通過Oauth2認證的這個部分。以Google Oauth2來說,最常用到的認證方式有兩種:

  • 代理使用者權限之操作:此部分操作為建置一個需要代理End User來執行操作的網頁應用程式,例如某個網站需要使用到使用者的Drive權限,以讀取特定Drive內文件或試算表等的資源做應用。這部分的認證操作,會需要該網頁應用程式先行申請Web Application Account,然後透過該Account所提供的Client ID, Client Secret以及Callback URL來作為認證的依據,並且在認證當下,系統必須指定所期望讓該Account所能夠存取存取的系統範圍,我們又稱:Scope。

  • 代理服務提供者權限之操作:此部分操作為讓終端使用者可以代理該應用程式的開發者權限來執行一些API呼叫,例如某家公司希望開發共用的BigQuery查詢服務,所有查詢都由統一的服務帳號(Service Account)操作,而非操作當下的使用者身份。

我們來參考Google官方提供的Node.js API中認證這塊的做法:

使用Google官方所提供的googleapis套件

先來看由Google官方提供的node.js套件”googleapis”(https://github.com/google/google-api-nodejs-client),它的運作模式是透過javascript的特性動態的binding所要使用的API所對應設定來使用該API,該套件中已收容大部份的Google API,足以讓開發者不用煩惱實作RESTful API呼叫的部分... 下面是載入googleapis的方法與初始化的流程:

實作Web Application認證

 在google-api-nodejs-client中,這個套件的初始化需要透過CLIENT_ID, CLIENT_SECRET, REDIRECT_URL等參數,這些參數其實是來自Google在認證部分的一些設定... 開發者可以在Google的Cloud Console中的”APIs & auth > Credentials”中申請”Web Application”的帳號:

當Web Application Accout建立後,應該在帳戶頁面會看到一組類似這樣的設定:

其中Client ID, Client Secret, Redirect URIs即是需要填寫到程式中的參數... 一般在實作Web Application Account時候,顧名思義是到時候這程式會執行為一個Web Server,具備一個IP或Domain,且在某個Port聆聽HTTP(s)需求,因此,在Redirect URIs的部分,我們需要填寫實際上瀏覽器可以連線到您Server的位置,例如您如果建立本機的測試環境,且聆聽3000 port,則該組設定在Authorized JavaScriopt origins中可以設定為”http://localhost:3000”,另外,我們需要定義Oauth2的返回呼叫網址(當Oauth2完成認證後,Oauth2 server會參照該網址來呼叫實作的Server,並且把相關的資訊提供給本地Server),假設我們設定路由”/oauth2callback”來接收返回呼叫,則在這邊可以設定Authorized redirect URIs為”http://”localhost:3000/oauth2callback“。而Oauth2之所以安全,跟這部分的設定有高度的關係,因此需要特別注意在這邊是否設定正確!

Google採用Oauth2的另一個原因在Oauth2所賦予的權限室友範圍的,我們一般將範圍稱作scope,並且在認證的過程中,傳遞給Oauth2 Server做建立Access Token的參考... 因此。在認證的設定部分完成後,接下來需要考慮該Web環境需要使用到哪些API的哪些權限,並且將他設定到scopes中,在generateAuthUrl()的部分帶入作為認證的依據。Scope的部分可以參考每個API的API文件做設定,而需要一次取得存取多個API的權限時,只需要將這些API的scope都放到scopes變數中即可。

透過generateAuthUrl()產生出來的URL經過user點選後會導到Google的認證頁面,讓user輸入帳號密碼,並且確認賦予您的Web Application您所指定的權限(程式中所設定的scopes),接著,使用者的畫面會導回到您在Cloud Console中所指定的返回呼叫網址(Callback URL),我們必須實作該URL來接收Oauth2 server所給予的資訊...

在googleapis套件中,返回呼叫功能的實作可以透過getToken來實作,其中code這個參數會在Google Oauth2 server返回的網址中以URL參數的方式帶入,在Node.js的Server中以query string的方式取出即可:

最後,Oauth2套件所返回的tokens物件,即包含access_token, refresh_token, expire_time等的資訊,讓後續的API可以依據這些資訊來做呼叫。

當Oauth2返回tokens物件後,一般我們可以透過Google Plus API來取回user所公開的資訊,做為系統認證的依據,然後就可以依照我們寫Web服務的習慣,設定使用者的session,並且參照自己設定的ACL讓使用者使用我們的系統。至於,需要存取其他API的部分,只要該API的Scope有正確設定在程式中,則我們可以透過下面的方式來呼叫Google的API:

透過setCredentials將access token與refresh token設定回oauth2Client實體,然後就可以讓需要存取的服務在呼叫的過程中來使用它。

實作Service Account之認證

另外,如果遇到Google為實作的API呢?!在Node.js中,我們可以以最真實的狀況模擬API的呼叫,而當中認證的部分則是帶入在HTTP呼叫的header中,以Node.js著名的request module來實作API的呼叫,我們可以這樣做:

上面展示的是透過第三方使用者的參與來做為認證的模式(代理使用者權限之操作),而在某一些情況,我們需要使用者可以使用開發者的專案權限來執行一些API呼叫,此時我們需要以Service Account為主的認證模式,這種認證方式需要在Cloud Console中申請Service Account,而在Google最新的認證方式中,已經改採用JSON key的方式來認證,減少使用者轉換金鑰的捆擾(早期p12 key的金鑰需要透過openssl的指令轉換成pem檔案方可在認證過程中採用):

建立好Service Account後,可以在Cloud Console中看到您的Service Account資訊如下:

並且系統提供您下載一組JSON key的檔案,該檔案格式大致如下:

在這組Service Account中,具備有client_email, private_key等資訊,這部分可以用來提交給googleapis模組的JWT認證方法,另外,我們尚需要提供欲使用到的scopes作為認證參數,最後,透過authorize()認證後,該方法會在callback函式中提供tokens,即為認證後的access_token等資訊...

接下來的操作可以在API的呼叫中帶入認證完的JWT client,或是透過request的方式來呼叫使用RESTful API...

Google API Explore

 在Google眾多API的操作中,一般文件所描述與實際上操作會有些許的落差,這時,通常我們可以參考Google所提供的API Explore服務(https://code.google.com/apis/explorer/)來測試我們所給訂的參數與了解回傳的內容之間的關聯。在API Explore中,我們可以找出所要操作的API以及愈操作的功能,然後透過右上角的”Authorize request using Oauth2.0”的認證開關來授與API Explorer可以以我們的權限來操作這個API。

在認證的當下,API Explore也會需要您授與可以存取的權限,在勾選出現的Scopes對話框內的scope之後,認證後的token需要確保您是否有權限存取這個API功能,當認證與權限授與沒有問題,接著就可以輸入您需要的值來存取該API方法了。

在API Explorer中實際執行的呼叫將會反映在該授與權限的專案中,因此操作上需要特別注意是否影響到運作中的環境,必要時建議測試與正式環境應該由Project Level就執行切割,避免影響到運作...
API Explorer的實際執行結果會顯示在該功能表單的下方,呈現的部分包含本次所呼叫的URL與所帶入的參數,再往下會有這次的回覆資訊,而目前大部份的輸出入會是以JSON的方式顯示。
結論

透過本文所描述的這些資訊,搭配Google所提供的API文件,開發者不難悠遊在Google的眾多API當中。加上Node.js在RESTful API存取上的彈性,我們更可以快速的處理每次的API呼叫,讓我們的服務得以更快速的結合Google既有的服務,為專案帶來無往不利的好處。
跳脫服務層面的API,Google在Cloud的各項應用上,也漸漸的將API的操作展開,讓像是Compute Engine、Cloud SQL、Cloud Storage… 或其他更底層的操作也可以透過API的呼叫方式來達成,這讓API成為銜接雲端服務的必要利器,也是新生代IT人必學的一門課程。

範例程式碼

請參考:https://github.com/peihsinsu/blog/tree/master/20150810-NodejsWithGoogleAPI-Example

 
關於JSDC
JSDC (JavaScript Developer Conference) 是台灣最⼤的JavaScript年度性技術研討會,旨在提供台灣JavaScript最新技術與討論 與分享,以及JavaScript人才的媒合。
更多介紹請看http://2015.jsdc.tw/zh_tw/

專欄作者


熱門新聞

Advertisement