[C#] MVC 實作 Google OAuth
最近專案有個介接Google帳號登入系統的需求,爬了一下文,大致上可行的做法就是用Google OAuth 讓使用者登入帳號後,可以回傳google帳戶的使用者資訊給我們系統,並依這些資訊查找我們的資料庫,是否有符合的帳號(可能比對回傳資訊的信箱),若沒有符合的資訊的話,則幫使用者建立一個帳號並進行登入動作。
實作:
1.先登入個人的Google帳號,並建立一個Google Api專案
2.建立好專案後,點擊左方「OAuth同意畫面」,選擇「外部」(提供所有擁有Google帳戶的人可以登入)
3.設定「OAuth」範圍(可以依專案需求選擇要回傳給系統的資訊或權限,這邊我先選擇一些基本資料,如Email的資訊)
4.新增測試使用者
*加入要測試的 Eamil 帳號為測試使用者。
5.點選「儲存並繼續」,並確認設定是否為自己的需求
6.建立OAth用戶端ID,在左邊點「憑證」,然後點「建立憑證」選擇「OAuth 用戶端 ID」
7.如果是 ASP.NET 串接的話,應用程式類型選擇「網頁應用程式」,名稱可以隨便取
8.建立授權的JavaScript來源與重新導向的URL,因為我這邊是本機測試,所以先用localhost的來源
9.OAuth 用戶端建立後會得到 ID 和密碼(目前介接資訊只需要用到「用戶端ID」)
11.建立一個「GoogleOAuthHelper」來處理取得介接資訊
/// Google OAuth Helper public static class GoogleOAuthHelper { /// <summary> /// Google Auth Callback URL /// </summary> public static string GoogleAuthCallback => $"{HttpContext.Current?.Request.Url.Scheme}://{HttpContext.Current?.Request.Url.Authority}/Home/{nameof(HomeController.GoogleCallBack)}".Trim('/'); /// <summary> /// Google ClientId /// </summary> public static string GoogleClientId => "30008552813-********jrrnvrde8127vao439i8h.apps.googleusercontent.com"; /// <summary> /// 驗證 Google Token /// </summary> /// <param name="controller">控制器 /// <returns></returns> public static GoogleJsonWebSignature.Payload VerifyGoogleToken(this Controller controller) { string formCredential = controller.Request.Form["credential"]; //回傳憑證 string formToken = controller.Request.Form["g_csrf_token"]; //回傳令牌 var cookiesToken = controller.Request.Cookies["g_csrf_token"].Value; //Cookie 令牌 // 檢查空值 if (formCredential == null || formToken == null && cookiesToken == null) { return null; } try { // 驗證 token if (formToken != cookiesToken) { return null; } // 驗證憑證 var settings = new GoogleJsonWebSignature.ValidationSettings() { Audience = new List <string>() { GoogleClientId } }; GoogleJsonWebSignature.Payload payload = GoogleJsonWebSignature.ValidateAsync(formCredential, settings).Result; if (!payload.Issuer.Equals("accounts.google.com") && !payload.Issuer.Equals("https://accounts.google.com")) { return null; } if (payload.ExpirationTimeSeconds == null) { return null; } else { DateTime now = DateTime.Now.ToUniversalTime(); DateTime expiration = DateTimeOffset.FromUnixTimeSeconds((long)payload.ExpirationTimeSeconds).DateTime; if (now > expiration) { return null; } } return payload; } catch { return null; } } }
12.在view 引用所有javaScript與 Google 登入按鈕
<div>
<div id="g_id_onload"
data-client_id="@GoogleOAuthHelper.GoogleClientId"
data-login_uri="@GoogleOAuthHelper.GoogleAuthCallback"
data-auto_prompt="false">
</div>
<div class="g_id_signin"
data-type="standard"
data-size="large"
data-theme="outline"
data-text="signin"
data-shape="rectangular"
data-logo_alignment="left">
</div>
</div>
@section scripts
{
<script src="https://accounts.google.com/gsi/client" async defer></script>
}
*按鈕生成後會長這樣,樣式可以在"g_id_signin"裡在依自己的需求調整,可以再看一下Google OAuth的官方文件
留言
張貼留言