[C#] 使用 Google 帳號登入 - 簡單實現從授權到用戶資料取得

2024-11-21

最近因為朋友在問我如何 透過 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.


當麻許的碎念筆記 2014 | Donma Hsu Design.