2016年2月16日 星期二

{Interview 專區} 什麼是Forms驗證 登入登出頁

今天要來說說FormsAuthentication
每個網站與應用程式幾乎都要用登入的功能
就是要驗證使用者是否有權限這件事
而我從來沒在實作FormsAuthentication的經驗
面試被問到的時候還是一臉茫然
然後面試官就覺的這是人生絕望的失望情結
其實真的不太懂,有這麼嚴重嗎?
這個東西,通常前輩寫了一回,後輩就不會去改動到
只有沒事的時候去「偷翻」然後摸一摸
但你覺的摸一摸就會寫
我的領悟力沒這麼高....

回到主題
using System.Web.Security 之下有FormsAuthentication這個類別
裡面就包好了很多寫好的程式,簡單來說就是做帳戶登入登出轉址等等
而這裡面的原理就是寫一個cookie在使用者的電腦,並用加密的方式保留著
點選擇登出才會刪除cookie,或是使用者去做「網際網路選項」裡面把cookie刪掉
不然就算關掉網頁,再打開網頁依然是登入的狀態,不少網頁都是這樣,就像我剛登入的博客來,而我沒清掉我的cookie

利用網路上的範例,終於實現自已寫出一個登入登出的頁面,也許老手會覺的這三小,而對不想研究技術的我來說,已經是一個目標達成

首先,這是一個MVC的範例
Control:
//以下所有未加AllowAnonymous者,都一定要經過login 成功才可以進入
[Authorize]
    public class MainController : Controller
    {
        //不一定要經過login 成功才可以進入
        [AllowAnonymous]
        public ActionResult Login()
        {
            return View();
        }
        [AllowAnonymous]
        [HttpPost]
        public ActionResult Login(Log_Xml logxml)
        {
            //這邊就會進到Log_Xml 做Validate func
            if (!ModelState.IsValid)
            {
                return View();
            }
            //要讓會員登入成「已驗證」狀態的話
            FormsAuthentication.RedirectFromLoginPage(logxml.Account, false);
         
            return null;
        }
        [AllowAnonymous]
        [HttpPost]
        public void LogOut()
        {
            //清除Session中的資料
            Session.Abandon();
            //登出表單驗證
            FormsAuthentication.SignOut();
            //導至登入頁
            //return RedirectToAction("Login", "Main");
        }
}


Model:
//主要要繼承IValidatableObject 覆寫Validate方法
public class Log_Xml : IValidatableObject
    {
        public string ReturnUrl { get; set; }

        /// <summary>
        /// 帳號
        /// </summary>
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        [Required]
        public string Account { get; set; }

        /// <summary>
        /// 密碼
        /// </summary>
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        [Required]
        public string Password { get; set; }
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            string base64Password = Convert.ToBase64String(Encoding.UTF8.GetBytes(Password));
            //進到xml取資料資料
            var source=ReadAndWriteXML();
            if(!source.Any(s=>s.UserId==Account && s.Password==base64Password))
            {
                yield return new ValidationResult("帳號密碼有誤", new string[] { "Account" });
            }
        }
        }


參考資料:
http://blog.miniasp.com/post/2008/02/20/Explain-Forms-Authentication-in-ASPNET-20.aspx
https://dotblogs.com.tw/shadow/archive/2014/03/01/144191.aspx