C# 學習筆記(二): Google Drive API 串接(OAuth 流程串接篇)

Tom
appxtech

--

嗨嗨大家好,這一篇的內容為 Google OAuth 流程的串接,主要內容都是直接參考下面這個官方文件,這篇只會把主要的架構流程記錄下來,詳細的資安需求則沒有放進來,有興趣的各位就照著文件內容補上吧~

專案建立

初始專案

首先,使用 dotnet 建立一個 webapi 的初始專案,把 “MyWebApiApp” 換成自己的專案名稱。

dotnet new webapi -n MyWebApiApp

Nuget Package 安裝

建立專案後安裝以下 Nuget Package。( 其他 Packages,如 DI 相關、AutoMapper、Swagger 等等的套件就自行處理囉~

  • Google.Apis.Auth
    進行 OAuth 授權流程
dotnet add package Google.Apis.Auth
  • Google.Apis.Drive.v3
    操作使者 Google Drive
dotnet add package Google.Apis.Drive.v3
  • System.IdentityModel.Tokens.Jwt
    針對 JWT 進行解碼,用在 IdToken 的解析。
dotnet add package System.IdentityModel.Tokens.Jwt

準備檔案

先新增幾個基本的檔案,後續的程式碼片段都分別添加在 GoogleController GoogleService,請看程式碼片段的左下角來判別檔案名稱。

  • appsettings.json : 此處 ClientId & ClientSecret 是第一篇申請的 OAuth 用戶端時填寫的內容,正常開發不該放在 appsettings.json 中,避免造成資安風險,不過此篇為學習筆記則以方便為主。
  • AppSettings.cs : 將 appsettings.json 物件化,方便依賴注入到物件中使用
  • GoogleController.cs
    Controller 的內容本系列不會開很多,大部分都是把 service 的 function 給出來而已,有需要進行測試的讀者就自行添加需要的 API 接口。
  • GoogleService.cs
  • Program.cs
    我的 DI 使用 Autofac 來做,若各位有其他習慣的方法都一樣可以。

Google OAuth 取得授權流程

下面這張圖是 Backend server 進行 Google OAuth 的流程圖。

Google OAuth flow for webapi server

照著上面的流程圖,就準備進行以下功能的開發。

1. 取得 OAuth URI.

首先第一步,要提供使用者進行 Google OAuth 授權的 URI 連結。

產生並回傳 OAuth URI
Swagger 測試取得 Google OAuth uri

這邊可以先簡單測試,把 uri 複製到瀏覽器看是否可以用,常見的錯誤情況有以下 :
1. 測試人員 email 未填入 : 申請時專案 User Type 選擇”外部”,並且專案未驗證與發佈則測試人員需要被加入名單才可使用。
2. Redirect URI 不一致 : GCP Console 與 OAuth URI 帶入的 Redirect URI 不相同,請確認以哪邊為準。
3. 其他問題則換瀏覽器試試,或下方提問~。

能看到以下的畫面基本上就沒有問題~

接著來處理 Redirect 回來後的事情。

2. Redirect URI API 接收 Google 回傳的 Authorization Code.

在 Google Controller 加上這支 API,用來接收回傳。
(GoogleService.ExchangeCodeForToken(code) 在下面)

Google Controller 新增 API 接收 Redirect request

當 Google 登入頁面的流程跑完之後,Google Server 就會將 Authorization Code 帶著打到我們給出去的 redirect uri,由我們的 API 接收,另外若 OAuth URI 產生的時候有帶著 State 參數也會一起帶回來。

不過 Authorization Code 畢竟還不是我們需要的 Access Token,所以還要再做一次的轉換,往下進行下一步。

3. 將 Authorization Code 轉為 Token.

在 Google Service 加上這個 function,將 code 轉為 token,這邊可以將取回的 token 存成檔案或是存到資料庫中,以利後續方便利用,請各位自行發揮。

注意: 這邊帶入 Google Library 的各種參數都必須跟上面產生 OAuth URI 所使用的一模一樣才行。

Google Service 將 Authorization code 轉換成 token 相關資訊

透過這段程式,就能將 Authorization Code 轉為 Token,Token 格式如下。

{
"accessToken": "ya29.a0AfB_byD8hxxxxxxxxxm....",
"tokenType": "Bearer",
"expiresInSeconds": 3599,
"refreshToken": "1//0evhoxxxxx....",
"scope": "https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/userinfo.email openid",
"idToken": "eyJhbGciOiJSUzI1NiIsImxxxxxxxx.......",
"issued": "2024-02-19T15:29:45.877155+08:00",
"issuedUtc": "2024-02-19T07:29:45.877155Z",
"isStale": false
}

到這一步後就可以進行完整個 Google OAuth 授權流程,再次在瀏覽器開啟 OAuth URI 頁面後完成授權,測試整個流程是否成功串起來,有看到回傳的 token 就沒問題了。

授權頁面 redirect 完成後回傳 tokens

4. 將 TokenResponse 轉換成 Credential

取得 Credential 是整個 OAuth 流程的最後一步,取得 credential 之後就可以帶著這個 Credential 去對使用者的帳號進行操作

Google Service 新增 function 負責將 token response 轉成 User Credential

5. 使用 Refresh Token 更新過期的 Access Token — 文件連結

OAuth 取回來的 access token 都有有效時間,過了這個時間則 access token 就會失效,所以這時候就需要用到 refresh token 來更新過期的 access token 來保證使用者的使用體驗,避免頻繁的登入。

Google controller 新增 API 來更新 access token
更新 access token 的 function
新增 refresh access token request dto
新增 update credential response dto
  • Swagger api 測試成功取得新的 access token

6. [補充]Decode Id Token — 文件連結

Id Token 本身是 JWT (JSON Web Token),所以可以直接 照著 Decode JWT 的方式取得其中資訊。

//使用方法 : 帶入 Id Token & 欲取得欄位名稱
var email = GoogleService.DecodeIdToken(idToken, "email");

以下是 Id Token 中可能包含的欄位

IdToken 可能包含的欄位

Google OAuth 的流程串接到這一步就告一段落了,這段過程可以套用在其他同樣是 google 的服務上,不必拘限於 Google Drive API 的串接,只需要把 API 的授權範圍調整即可。

本篇到此結束啦,謝謝各位。

--

--

Tom
appxtech
Writer for

Major in Computer Science, Web Backend Engineer