最近因為朋友在問我如何 透過 Google 登入,並且取得用戶的資料,上網查一下,其實是有套件
但是因為對方需求,相關套件不方便入手或無法滿足特定需求,直接使用 C# 來實作 OAuth 機制統合是一個好方式。
今天筆記一下如何 透過純 OAuth 來做到,在 .NET 8 + ASP.NET 中實作 Google
OAuth2 驗證。
OAuth2 流程概述
OAuth2 是一種安全的授權協定,通常用於認證與認識網站用戶。此次實作使用的流程如下:
1.在 Google Cloud Developer 後台拿到開發資訊,這一步最難,不得不說 那邊非常複雜,我分享兩張圖
你自己想辦法,找到這兩個值吧 用戶端編號 client_id,跟用戶端密碼 client_secret


2.讓用戶前往 Google OAuth2 的授權頁面。
public IActionResult OnPostGooogleAuth()
{
//跳轉先去拿到code
return new RedirectResult("https://accounts.google.com/o/oauth2/v2/auth?" +
"response_type=code" +
"&client_id=" + clientId+
"&redirect_uri=" + HttpUtility.UrlEncode(redirectUrl) +
"&include_granted_scopes=true"+
"&scope=https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid" +
"&state=donmaid" +
"" + DateTime.Now.ToString("yyMMddHHmmss"));
}
3.用戶授權後你會在 redirect_url 收到一個用戶 code。
public void OnGet()
{
if (!string.IsNullOrEmpty(Request.Query["code"]))
{
GoogleAccessToken = Request.Query["code"];
}
if (!string.IsNullOrEmpty(Request.Query["state"]))
{
InnerUserId = Request.Query["state"];
}
}
4.用戶 code 換取認證的 access token。
/// <summary>
/// 透過 user code 拿到 access token
/// </summary>
/// <param name="clientId"></param>
/// <param name="cluentSecret"></param>
/// <param name="userCode"></param>
/// <returns></returns>
public string GetAccessTokenByCode(string clientId, string clientSecret, string userCode) {
var client = new RestClient("https://accounts.google.com/o/oauth2/token");
var request = new RestRequest(new Uri("https://accounts.google.com/o/oauth2/token"), Method.Post);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("client_id", clientId);
request.AddParameter("client_secret", clientSecret);
request.AddParameter("grant_type", "authorization_code");
request.AddParameter("code", userCode);
request.AddParameter("redirect_uri", redirectUrl);
try
{
var response = client.ExecuteAsync(request).Result;
if (response.IsSuccessful)
{
return response.Content;
}
else
{
return ($"Error: {response.StatusCode} - {response.ErrorMessage}");
}
}
catch (Exception ex)
{
return ("Exception occurred: " + ex.Message);
}
}
//Response:
/*
{"access_token": "access_token_code", "expires_in": 3597,
"scope": "openid https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile",
"token_type": "Bearer", "id_token": "id_token" }
/*
5.通過 access token 取得用戶資料。
/// <summary>
/// 透過 user token 拿到 user profile
/// </summary>
/// <param name="accesstoken"></param>
/// <returns></returns>
public string GetGooogleUserInfoByAccesstoken( string accesstoken)
{
var client = new RestClient("https://www.googleapis.com/oauth2/v3/userinfo?access_token="+accesstoken);
var request = new RestRequest(new Uri("https://www.googleapis.com/oauth2/v3/userinfo?access_token=" + accesstoken), Method.Get);
try
{
var response = client.ExecuteAsync(request).Result;
if (response.IsSuccessful)
{
return response.Content;
}
else
{
return ($"Error: {response.StatusCode} - {response.ErrorMessage}");
}
}
catch (Exception ex)
{
return ("Exception occurred: " + ex.Message);
}
}
//Result
/*
{ "sub": "110525762531932290727", "name": "Hsu DMA", "given_name": "Hsu",
"family_name": "DMA", "picture":
"https://lh3.googleusercontent.com/a/ACg8ocJRBsgW_uCQGHXATIm9ODBqmNrE9gpbE7dg1qg_Od0XdfJCOL5q\u003ds96-c",
"email": "sample@gmail.com", "email_verified": true }
*/
就簡單筆記一下,方便之後自己 copy paste.