[ASP.NET MVC] 前台會員使用 Cookie 保持登入狀態範例教學 #CH5
在學習 C# 與資料庫的互動方式,有一個常見且實用的教學就是會員登入、註冊與修改會員資料等範例,學習過程中會用到資料庫新增、修改與查詢動作,是理解程式與資料庫互動的常見程式碼。
當學會了這個範例,將來為客戶開發系統的時候,馬上可以派上用場。
此篇文章是繼上一篇文章: 前台會員忘記密碼與重設密碼範例教學 #CH4 接續教學。
此範例展示會員登入時勾選保持登入,程式記錄會員資訊在 Cookie ,等待下次登入時,先從 Cookie檢查是否已登入過。
範例內容主要以 ASP.NET MVC 為核心,前端使用 Vue.js 框架,而後端使用 SQL Server 當資料庫。
文末有提供此操作範例的完整程式碼下載,有需要可以自行下載瀏覽。
Contents
增加保持登入勾選
打開登入頁範例 \Views\Member\Login.cshtml 在登入按鈕上方加入勾選。
1 2 3 4 5 6 |
<div class="checkbox"> <label> <input class="form-check-input" type="checkbox" value="true" id="chkKeepLogin" v-model="form.KeepLogin"> 保持登入 </label> </div> |
在執行登入按鈕時會呼叫的 DoLogin()
方法修改一下,加入 KeepLogin 參數傳送到後端。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
// 執行登入按鈕 DoLogin: function () { var self = this; // 組合表單資料 var postData = {}; postData['UserID'] = self.form.UserID; postData['UserPwd'] = self.form.UserPwd; postData['KeepLogin'] = self.form.KeepLogin; // 使用 jQuery Ajax 傳送至後端 $.ajax({ url:'@Url.Content("~/Member/DoLogin")', method:'POST', dataType:'json', data: { inModel: postData }, success: function (datas) { if (datas.ErrMsg) { alert(datas.ErrMsg); return; } alert(datas.ResultMsg); // 導向到修改個人資料頁面 window.location = '@Url.Content("~/Member/EditProfile")'; }, error: function (err) { $('#ErrorMsg').html(err.responseText); $('#ErrorAlert').modal('toggle'); }, }); } |
登入成功寫入 Cookie
接著到 \Controllers\MemberController.cs 的頁面,找到 public ActionResult DoLogin(DoLoginIn inModel)
方法。
在程式碼 outModel.ResultMsg = "登入成功";
之後繼續加入新程式碼。
1 2 3 4 5 6 7 8 9 |
// 檢查是否保持登入 if (inModel.KeepLogin == "true") { HttpCookie ckUserKeepLogin = new HttpCookie("UserKeepLogin"); //Cookie 名稱 ckUserKeepLogin.Value = inModel.UserID; //Cookie 值 ckUserKeepLogin.Expires = DateTime.Now.AddDays(7); //Cookie 有效期限 ckUserKeepLogin.HttpOnly = true; //防止 XSS 攻擊 Response.Cookies.Add(ckUserKeepLogin); } |
此段程式碼是建立一個 Cookie 值放在使用者的瀏覽器上面,記錄著帳號及密碼,等待下次登入時,可以檢查。
Cookie 資安防護機制
當在編寫 Cookie 時要注意資安防護的 XSS 攻擊,尤其是具有登入身份的驗證機制,一定要建立安全檢查,避免駭客利用竊聽偷取你的 Cookie 就可以偽造你的身份。
程式碼中有一行 ckUserKeepLogin.HttpOnly = true;
就是在 Cookie 設定禁止 Javascript 存取 Cookie。
除了設定 HttpOnly 之外,網站還需要啟用 SSL 憑證的 https 協定,兩者加起來才可以有效防止 XSS 攻擊。
調整登入 Model 參數
在 Controller 有增加新參數,所以要在 Model 也加入新參數,開啟 \Models\MemberModel.cs 頁面,在 DoLoginIn
的類別內加入新參數。
1 |
public string KeepLogin { get; set; } |
檢查是否已登入
假設我們已經成功登入帳號,當再次開啟登入畫面時,我們先在程式檢查 Cookie 是否已登入,如果已登入,就可以跳過登入畫面,直接進入會員專區。
開啟 \Controllers\MemberController.cs 頁面,直接在 public ActionResult Login()
方法內增加語法。
修改後的 public ActionResult Login()
語法如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
// GET: 登入頁面 public ActionResult Login() { if (Request.Cookies["UserKeepLogin"] != null) { if (!string.IsNullOrEmpty(Request.Cookies["UserKeepLogin"].Value)) { // 取出帳號 string UserID = Request.Cookies["UserKeepLogin"].Value; // 資料庫連線 string connStr = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["ConnDB"].ConnectionString; SqlConnection conn = new SqlConnection(); conn.ConnectionString = connStr; conn.Open(); // 檢查帳號、密碼是否正確 string sql = "select * from Member where UserID = @UserID"; SqlCommand cmd = new SqlCommand(); cmd.CommandText = sql; cmd.Connection = conn; // 使用參數化填值 cmd.Parameters.AddWithValue("@UserID", UserID); // 執行資料庫查詢動作 SqlDataAdapter adpt = new SqlDataAdapter(); adpt.SelectCommand = cmd; DataSet ds = new DataSet(); adpt.Fill(ds); if (ds.Tables[0].Rows.Count > 0) { // 有查詢到資料,表示帳號密碼正確 // 將登入帳號記錄在 Session 內 Session["UserID"] = UserID; //給前端的資訊 ViewData["UserKeepLogin"] = "Y"; // 繼續延長 Cookie 時間 HttpCookie ckUserKeepLogin = new HttpCookie("UserKeepLogin"); //Cookie 名稱 ckUserKeepLogin.Value = UserID;//Cookie 值 ckUserKeepLogin.Expires = DateTime.Now.AddDays(7); //Cookie 有效期限 ckUserKeepLogin.HttpOnly = true; //防止 XSS 攻擊 Response.Cookies.Add(ckUserKeepLogin); } } } return View(); } |
從 Request 裡面取出 Cookie 值,向資料庫驗證身份,當檢查成功之後,就可以回傳參數給 View,View 再依參數導向其他頁面。
View 檢查保持登入參數
開啟 \Views\Member\Login.cshtml 頁面,可以建立 Vue.js 的 mounted 事件來檢查是否已登入參數。
在 Vue.js 的事件加入以下程式碼。
1 2 3 4 5 6 7 8 |
, mounted: function () { let UserKeepLogin = '@ViewData["UserKeepLogin"]'; if (UserKeepLogin == "Y") { alert("已經登入過了喔"); // 導向到修改個人資料頁面 window.location = '@Url.Content("~/Member/EditProfile")'; } } |
測試保持登入
按 F5 開啟網頁,在登入頁面勾選「保持登入」,輸入帳號密碼執行登入。
登入成功後,會導向修改個人資料範例頁。
這時候可以關閉網頁,再重開瀏覽器,再到登入頁面,如果是過去的狀態,會因為 Session 已改變,造成使用者需要重新登入才可以。
使用 Cookie 記錄帳號密碼之後,就可以從 Cookie 裡面檢查使用者身份,不必讓使用者再次輸入帳號密碼。
這時候再重新回到登入後,就會檢查 Cookie 值內是否已登入過,Cookie 檢查成功,就會出現 alert 訊息。
重點整理
- 使用 Cookie 記錄會員身份
- 增加保持登入勾選鈕
- 登入成功寫入 Cookie
- 在需要登入頁面檢查 Cookie
範例下載
此範例包含完整範例內容,連結 GitHub 下載範例
相關學習文章
- [ASP.NET MVC] 前台會員註冊範例 #CH1
- [ASP.Net MVC] 免費公司形象網站範本套版 #CH1 (附範例)
- [ASP.NET MVC] 前後台網站公告範例 – 後台查詢頁面教學 #CH1 (附範例)
如果你在學習上有不懂的地方,需要諮詢服務,可以參考站長服務,我想辨法解決你的問題
如果文章內容有過時、不適用或錯誤的地方,幫我在下方留言通知我一下,謝謝
直接把密碼存在cookie不是一個好的做法喔!
那請問一下,那比記憶密碼更好的方式有什麼好建議嗎
不好意思 想請問一下 登出的部分該怎麼進行呢?
我原本想說您登入驗證是以session存檔
所以下了Session.Abandon(); 在controller中 但它並沒有起作用
登出的話,其實簡單的做法就是執行 Session[“UserID”] = “”; 就可以了
不好意思 想再請問一下 登出的部分已經完成
但原本登入時產生的UserKeepLogin 這個Cookies卻無法刪除 請問老師有什麼方法可以清除他嗎
這個你可以試試看
HttpCookie ckUserKeepLogin = new HttpCookie(“UserKeepLogin”); //Cookie 名稱
ckUserKeepLogin.Value = “”; //Cookie 值
ckUserKeepLogin.Expires = DateTime.Now; //Cookie 有效期限
ckUserKeepLogin.HttpOnly = true; //防止 XSS 攻擊
Response.Cookies.Add(ckUserKeepLogin);
想請問一下,設置了cookie之後我想執行其他程式碼時卻無法獲得身分驗證是甚麼原因,我已經成功登入了,但是驗證這塊會沒有辦法讓我去抓到我的帳號名稱