第三方登入系列文章的第六篇,「在 ASP.NET Core 整合 Twitter 做第三方登入」,應該也是最後一篇了,最近這一段時間討論度最高的社群平台應該就是 Twitter 了,不知道一龍這樣搞下去,Twitter 的未來會怎麼樣?不過在台灣來講,使用 Twitter 的人比例是比較小的,若是我們的應用程式的主要服務對象是在美國或是日本,Twitter 的第三方登入可能就有其必要性,整個整合的過程,就記錄在這篇文章當中。
其他的第三方登入解決方案可以參考下面的連結:
- 在 ASP.NET Core 整合 LINE Login 做為網站的第三方登入
- 在 ASP.NET Core 整合 Facebook 做為網站的第三方登入
- 在 ASP.NET Core 整合 Google 做為網站的第三方登入
- 在 ASP.NET Core 整合 Microsoft 做為網站的第三方登入
- 在 ASP.NET Core 整合 GitHub 做為網站的第三方登入
建立 App
第一步我們先在 Twitter 上建立 App,在建立 App 之前先要建立 Project,我們到 Twitter 的 developer portal’s App page,點擊「Create Project」,一路按照步驟填入「Project name」、「Use case」、「Project description」,Project 就能建立起來。




Project 建立完成後,會自動跳到建立 App 的畫面,填入「App name」後按下「Next」,看到 API Key、API Key Secret、Bearer Token 都產生出來之後,App 就建立成功了。


接下來,我們要取得 Client ID 及 Client Secret,我們切換到應用程式的設定頁面,點擊「Set up」。

在開啟的設定畫面中,將必填欄位填一填,其中「App permissions」就按照我們的需要去選擇,「Type of App」請選擇 Confidential client,「Callback URI / Redirect URL」填入規劃好的 Callback URL,「Website URL」填入應用程式的相關網頁,然後按下「Save」。

跳出來的視窗就會顯示我們的 Client ID 及 Client Secret,複製下來備用。

準備 Redirect URL
接下來,我們要來撰寫 Redirect URL 的程式了,使用者授權成功後,Twitter 會將 code 回傳到我們的 Web Api,我們再拿這個 code 發送 POST 去跟 Twitter 交換 Access Token,再拿 Access Token 去跟 Twitter 拿使用者授權的資料,下面是交換 Access Token 時,所需的參數:
Access Token URL:https://api.twitter.com/2/oauth2/tokenUser Info Url:https://api.twitter.com/2/users/me?user.fields=id,name,profile_image_urlclient_id:即 Client IDclient_secret:即 Client Secretcode:即我們拿到的 coderedirect_uri:即 Callback URI / Redirect URLcode_verifier:一個隨機字串,必須搭配授權網址中的code_challenge及code_challenge_method一起使用,在 OAuth 2.0 PKCE(Proof Key for Code Exchange) 模式中扮演答案的角色。
關於 OAuth 2.0 PKCE 模式的運作是這樣的,我們會在授權網址中將 code_challenge 及 code_challenge_method 送給 Twitter,而 code_challenge 的值是依據 code_challenge_method 所指定的方式,將 code_verifier 進行轉換得來的,而 code_challenge_method 有兩種選擇,分別是 plain 及 S256,詳細的轉換邏輯可以參考 RFC 7636 - 4.2 Client Creates the Code Challenge。
我們在跟 Twitter 交換 Access Token 的時候,需要將 code_verifier 送給 Twitter,Twitter 會將收到 code_verifier 再依據 code_challenge_method 指定的方式轉換過後,與 code_challenge 進行比對,比對相同才能通過驗證。
程式原始碼如下:
[HttpGet("callback")]
public async Task<IActionResult> Callback()
{
if (!this.Request.Query.TryGetValue("code", out var code))
{
return this.StatusCode(400);
}
var oauthToken = await this.ExchangeAccessToken(code);
if (oauthToken == null)
{
return this.StatusCode(400);
}
var userInfo = await this.GetUserInfo(oauthToken);
// TODO: Save AccessToken and UserProfile
// TODO: User Login
return this.Redirect("/");
}
private async Task<string> ExchangeAccessToken(string code)
{
var client = this.httpClientFactory.CreateClient();
var request = new HttpRequestMessage(HttpMethod.Post, "AccessTokenUrl");
// 將 Client ID 及 Client Secret 以 Basic Authentication 的方式塞進 Header
var authorization = Convert.ToBase64String(
Encoding.UTF8.GetBytes($"{ClientId}:{ClientSecret}"));
request.Headers.Authorization = AuthenticationHeaderValue.Parse($"Basic {authorization}");
request.Content = new FormUrlEncodedContent(
new Dictionary<string, string>
{
["grant_type"] = "authorization_code",
["code"] = code,
["redirect_uri"] = "RedirectURI",
["code_verifier"] = "CodeVerifier"
});
var response = await client.SendAsync(request);
if (response.StatusCode != HttpStatusCode.OK) return null;
var content = await response.Content.ReadAsStringAsync();
var result = JsonNode.Parse(content);
return result["access_token"].GetValue<string>();
}
private async Task<string> GetUserInfo(string accessToken)
{
var client = this.httpClientFactory.CreateClient();
var request = new HttpRequestMessage(HttpMethod.Get, "UserInfoUrl");
request.Headers.Authorization = AuthenticationHeaderValue.Parse($"Bearer {accessToken}");
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();
return result;
}
授權網址
再來要兜出授權網址給使用者登入用,Twitter 的授權網址為 https://twitter.com/i/oauth2/authorize,所需要的參數如下:
client_id:即 Client IDredirect_uri:即 Callback URI / Redirect URLstate:隨機產生的一段唯一的字串,主要是可以用來避免 CSRF(Cross Site Request Forgery)。scope:想請使用者授權給我們的資料範圍,可參考 OAuth 2.0 Authorization Code Flow with PKCE | Docs | Twitter Developer Platform。code_challenge:請參考上面關於 OAuth 2.0 PKCE 模式的說明code_challenge_method:請參考上面關於 OAuth 2.0 PKCE 模式的說明,我選用 S256。
在這邊我們可能會遇到 code_verifier 及 code_challenge 如何產生的問題?這個部分我們除了根據 RFC 7636 所制定的邏輯自行撰寫之外,也可以利用網路上現成的 Online PKCE Generator Tool 來產生。
所以我根據我所取得資料,兜出了下面這個授權網址:
登入的流程跑起來大概像下面這張圖:

使用者點擊授權網址,透過 Twitter 的介面授權成功之後,我們拿到了使用者授權的資料,就算是整合成功了。


Twitter 目前正處於風雨飄搖的狀態,你我都正在見證著,祝福能夠有個好的結果,以上,整合 Twitter 第三方登入就分享給大家,希望對大家能夠有一點幫助。
參考資料
- OAuth 2.0 | Docs | Twitter Developer Platform
- OAuth 2.0 Making requests on behalf of users | Docs | Twitter Developer Platform
- Getting started with Postman
- Twitter API v2 calls
- Proof Key for Code Exchange

