[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」)


ps:ID跟密碼可以回看,所以不用擔心忘記


10.在專案Nuget下載「Google.Apis.Auth」

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的官方文件


13.Controller 結構


14.結果,成功取得介接回來得資訊



留言

這個網誌中的熱門文章

[Visual Studio]位於網際網路或是限制區域上 或是檔案上標有 web 字樣 所以無法處理該檔案。若希望處理這些檔案 請移除 web 字樣。

[IIS] IIS執行時,發生拒絕存取路徑 問題

[windows] xcopy 備份至 「網路磁碟機」