[料理佳餚] 在 ASP.NET Core 整合 Google 做為網站的第三方登入

第三方登入系列文章的第三篇,在 ASP.NET Core 整合 Google 做第三方登入,Google 就無需再多做介紹了,全世界最大的搜尋引擎,也是數一數二的綜合網路服務供應商,光 Gmail 就有超過 18 億的使用者,這篇文章記錄了與 Google 整合第三方登入的過程。

其他的第三方登入解決方案可以參考下面的連結:

新增專案

這個步驟不是必要的,假如我們在 Google Cloud 已經有合適的專案,可以跳過這個步驟,沒有的話,我們到 Google Cloud 的後台新增一個專案。

然後,新增完成後,記得切換到剛剛新增的專案。

註冊應用程式

使用 OAuth 2.0 整合第三方登入,一定得先讓平台認識我們的應用程式,第一步我們先來註冊我們的應用程式,在漢堡選單中點選「OAuth 同意畫面」,從這裡去註冊應用程式。

接著,選擇應用程式的使用者類型,如果應用程式是專屬於機構內部人員使用,可以選擇「內部」,而我這邊是要開放給外部使用者使用的,因此選擇「外部」。

下面就進入了註冊流程,第一個畫面是「OAuth 同意畫面」,把必填欄位填一填之後,點擊「儲存並繼續」。

第二個畫面是「範圍」,這裡我們先不輸入任何資料,點擊「儲存並繼續」。

第三個畫面是「測試使用者」,應用程式在開發期間只有測試名單內的使用者才能存取,所以這邊我們需要指定測試使用者,都輸入完後,點擊「儲存並繼續」,到這邊應用程式就註冊成功了。

建立 OAuth 2.0 用戶端 ID

Google 的玩法是一個專案只能有一個應用程式,要多個應用程式的話就建多個專案,但是一個應用程式可以有多個 OAuth 2.0 用戶端 ID,給不一樣的授權流程使用,接下來,我們就要來請 Google 發給我們一個 OAuth 2.0 的用戶端 ID,點擊左邊選單內的「憑證」。

接著,點擊「建立憑證」,選擇「OAuth 用戶端 ID」。

下面這邊「應用程式類型」選擇「網頁應用程式」,就會跳出來相應的欄位,將必填的欄位填一填之後,點擊「建立」。

其中「已授權的重新導向 URI」,雖然我們還沒開發好,但是這個網址如果已經知道了,可以先填進去,省得之後再回頭來修改。

當我們看到下面這個畫面之後,OAuth 2.0 用戶端 ID 就算是建立成功了,將「您的用戶端 ID」及「您的用戶端密碼」複製下來備用。

準備已授權的重新導向 URI

我們要進入到程式開發的環節了,先開發 Redirect URI,Google 會在使用者完成授權的時候,將 code 丟回給我們,屆時我們再拿 code 發一個 POST 去跟 Google 交換 Access TokenIdToken,所需要參數如下:

  1. AccessTokenUrl:https://oauth2.googleapis.com/token
  2. grant_type:填入 "authorization_code"
  3. code:即我們拿到的 code
  4. redirect_uri:即 Redirect URI
  5. client_id:即用戶端編號
  6. client_secret:即用戶端密碼

Redirect URI 的程式碼如下:

[HttpGet("callback")]
public async Task<IActionResult> Callback()
{
    if (!this.Request.Query.TryGetValue("code", out var code))
    {
        return this.StatusCode(400);
    }

    var (accessToken, idToken) = await this.ExchangeAccessToken(code);

    if (accessToken == null)
    {
        return this.StatusCode(400);
    }

    // TODO: Save AccessToken and IdToken

    // TODO: User Login

    return this.Redirect("/");
}

private async Task<(string, string)> ExchangeAccessToken(string code)
{
    var client = this.httpClientFactory.CreateClient();

    var request = new HttpRequestMessage(HttpMethod.Post, "AccessTokenUrl");

    request.Content = new FormUrlEncodedContent(
        new Dictionary<string, string>
        {
            ["grant_type"] = "authorization_code",
            ["code"] = code,
            ["redirect_uri"] = "RedirectURI",
            ["client_id"] = "ClientId",
            ["client_secret"] = "ClientSecret"
        });

    var response = await client.SendAsync(request);

    if (response.StatusCode != HttpStatusCode.OK) return (null, null);

    var content = await response.Content.ReadAsStringAsync();

    var result = JsonNode.Parse(content);

    return (result["access_token"].GetValue<string>(), result["id_token"].GetValue<string>());
}

授權網址

接下來我們要來兜授權網址,使用者點擊授權網址之後,就開始登入的流程,Google 的授權網址是 https://accounts.google.com/o/oauth2/v2/auth,所需參數如下:

  1. response_type:填入 "code"
  2. client_id:即用戶端編號
  3. redirect_uri:即 Redirect URL
  4. state:隨機產生的一段唯一的字串,主要是可以用來避免 CSRF(Cross Site Request Forgery)
  5. scope:想請使用者授權給我們的資料範圍

由上述參數所兜出來的網址如下:

https://accounts.google.com/o/oauth2/v2/auth?client_id=xxx&redirect_uri=http%3A%2F%2Flocalhost%3A5101%2Fgoogle%2Flogin%2Fcallback&state=12345abcde&response_type=code&scope=openid%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email

整個登入的流程如下圖:

當使用者瀏覽授權網址之後,就會導到 Google 的登入授權畫面,授權成功後,進到我們系統,拿到使用者資料就算是整合成功了。

以上,使用 ASP.NET Core 整合 Google 做第三方登入的步驟,就分享給大家,希望大家都能夠整合順利。

參考資料

相關資源

C# 指南
ASP.NET 教學
ASP.NET MVC 指引
Azure SQL Database 教學
SQL Server 教學
Xamarin.Forms 教學