[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的官方文件
留言
張貼留言