在前篇文章中簡單介紹如何在網站應用程式中取得 Google OAuth 2.0 授權, 本篇文章要說明的是如何在「已安裝應用程式中取得 Google OAuth 2.0 授權」。 這二者的授權流程是相似的,比較相異的有以下三點:
- 申請的憑證類型不同,必須是「已安裝應用程式」類型。
- 憑證中的 Client ID, Client Secret 是嵌在程式碼之中的。
- OAuth Server 回傳的 Authorization Code 是直接放在應用程式的 Title bar 或者 http://localhost 網址的參數中。
另外要注意的是,若要使用「已安裝應用程式」類型,你的系統中必須含有預設的瀏灠器,並且該應用程式有權限存取該瀏灠器。
申請「已安裝應用程式」憑證
存取 Google API 必須先至 Google Developers Console 申請應用程式憑證。
取得 Access Token
若是要在已安裝的應用程式中取得存取憑證,做法也可以參考上一篇<在網站應用程式中取得 Google OAuth 2.0 授權>的作業流程,以取得存取憑證。 只不過這麼一來,就必須透過 Browser 元件自行處理回應的訊息。 另外較方便的方式就是下載 Google 提供的「用戶端類別庫」,可以在已安裝的應用程式中很方便的取得 OAuth 2.0 的存取憑證。
類別庫下載
- Google APIs OAuth Client Library
- Google APIs Client Library
- Google APIs Core Library
UserCredential 和 AuthorizationCodeFlow
Google API OAuth 類別庫中,它透過 GoogleWebAuthorizationBroker.AuthorizeAsync 靜態方法來建立 UserCredential 類別,以便向 Google 服務取得 access token 。 UserCredential 是類別庫中,用來記錄 access token 的物件,並且可以在憑證過期時自動 refresh token 。 而 GoogleWebAuthorizationBroker 則是一個 Code Flow 類型的物件,也就是它在執行時其實是包含多個步驟,它會依實際狀況,自動執行必要的步驟。 例如,如果程式找不到本機端儲存的 access token ,則會開啟使用者 consent 頁面,等待使用者授權程式存取他的資料。 如果使用者按下了同意按鈕,應用程式將自動取得 access token ,並將值保存下來,留待下一次執行時使用。 如果該 access token 已過有效期限已,就會自動送出 refresh token 以便更新 access token 。 這一連串的步驟 Google OAuth2 API 都已經包裝起來,我們只要照以下程式碼的設定即可。
下面這個例子,Broker 會將憑證資料儲存在底下這個檔案中: "%AppData%\Roaming\Google.Apis.Auth\Google.Apis.Auth.OAuth2.Responses.TokenResponse-user"。
public UserCredential GetCredential() { UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync( new ClientSecrets { ClientId = "XXXX.apps.googleusercontent.com", ClientSecret = "et-OimYoEOwuhQgrFaoNInwv", }, new[] { "https://www.googleapis.com/auth/blogger" }, "user", CancellationToken.None ).Result; return credential; }
底下簡單說明建立 UserCredential 物件時,會使用到的參數值:
ClientSecrets
在使用 Blogger API 時,你必須先替應用程式申請一組憑證(申請方法請看<Google OAuth 2.0>),再使用核發憑證中的 ClientID 和 Secret 建立 ClientSecrets 。 當 request 無法獲得有效的 access token 時,則必須使用這組資訊,重新建立 access token 。 另外,你也可以將當初向 Google 申請的憑證下載回來,然後在建立 ClientSecrets 時,直接使用開啟檔案的方法,匯入憑證。例如:
public UserCredential GetCredential() { UserCredential credential; using (var stream = new FileStream(@"d:\mydll\client_secrets.json", FileMode.Open, FileAccess.Read)) { credential = GoogleWebAuthorizationBroker.AuthorizeAsync( GoogleClientSecrets.Load(stream).Secrets, new[] { "https://www.googleapis.com/auth/blogger" }, "userxxx", CancellationToken.None, new FileDataStore("Auth.Blogger")).Result; } return credential; }
若要下載已申請的憑證,你可以到 Google Console 網站中找到以下連結。
Scope
AuthorizeAsync 這個方法中的 scope 指的是授權內容的範圍。 在 Google 的 OAuth 實作中,定義了很多 scope ,例如:Blogger、Picasa、Google Map 等等, 當程式開發時,就利用這個參數來告訴 Google 開啟相關的授權資訊讓使用者 consent 。
例如,若 scope = BloggerService.Scope.Blogger ,授權頁的內容如下:
例如,若 scope = BloggerService.Scope.BloggerReadonly ,則授權頁的內容如下:
user_account
第3個參數,只是用來識別不同的使用者,如果這個用戶端程式只有一個人使用,那麼使用任何一個固定的字串也是可以的。
CancellationToken
這個參數是用來設定授權作業時是否可以被中斷。
FileDataStore
第5個參數是用來指定存放 access token 的目錄,你可以指定一個 File Store 或者 Data Store 物件當做參數值。 這個參數非必要欄位,如果沒有指定,則會自動儲存在預設的位置。 預設的位置會使用 "Google.Apis.Auth" 當做參數值,然後將這個目錄建立在 Environment.SpecialFolder.ApplicationData 之中。 所以上面例子中,Broker 會由 d:\mydll\client_secrets.json 讀取用戶端憑證資料,並將使用者授權後的存取憑證資料儲存在底下這個檔案中: "%AppData%\Roaming\Auth.Blogger\Google.Apis.Auth.OAuth2.Responses.TokenResponse-userxxx"。
更新與撤銷存取憑證
當應用程式取得使用者的 OAuth 授權後,若需要更新或撤銷憑證,也可以直接叫用 UserCredential 的方法即可。
/// 更新授權憑證 credential.RefreshTokenAsync(CancellationToken.None) /// 撤銷授權憑證 credential.RevokeTokenAsync(CancellationToken.None)
沒有留言:
張貼留言