簡易的達成前端送出時欄位驗證
以及後端登入驗證
實作方式的紀錄
前置作業
首先建一個Model
設定一些前端驗證規則給前端用
因為沒有要實作撈DB資料那段所以把後端模擬測試用的CODE也在在這裡
public class MyAccount
{
[Required]
[StringLength(6, ErrorMessage = "帳號不能大於6碼!")]
[Display(Name = "帳號")]
public string UserName { get; set; }
[Required]
[StringLength(6, ErrorMessage = "密碼不能大於6碼!")]
[Display(Name = "密碼")]
public string Password { get; set; }
public int Rank { get; set; }
public MyAccount(string _UserName,string _Password)
{
string simulatio_DB_Password = "abc123"; //假裝從DB撈回來的
if (_Password == simulatio_DB_Password)
{
this.UserName = _UserName;
this.Password = simulatio_DB_Password;
this.Rank = 0;
}
}
}
開始做VIEW的部分
step1. 先到controller中建立一個ActionResult
public ActionResult Logon()
{
return View();
}
接著右鍵新增view
step2. 在Logno.cshtml中加入帳號密碼輸入欄位..等
@using (Html.BeginForm("Logon", "Home", FormMethod.Post))
{
/*
AntiForgeryToken可防止CSRF攻擊,前端放一把鑰匙
後端有個對應的門鎖[ValidateAntiForgeryToken]
沒有鑰匙就無法通過
用來防止偽造的請求
*/
@Html.AntiForgeryToken()
@Html.LabelFor(x => x.UserName) //<--標題
@*@Html.DisplayNameFor(x => x.UserName) //也可以用這個*@
@Html.TextBoxFor(x => x.UserName) //<--Input text 欄位
@Html.ValidationMessageFor(x => x.UserName) //<--驗證訊息
@Html.LabelFor(x => x.Password) //<--標題
@Html.PasswordFor(x => x.Password) //input password 欄位
@Html.ValidationMessageFor(x => x.Password) //<--驗證訊息
<input type="submit" />
}
step3. 在Logno.cshtml下方加入Script (少了這支前端就沒有驗證功能了)
@section scripts{
@Scripts.Render("~/bundles/jqueryval")
}
再來做Controller的部分
Logon的ActionResult會有2個
一個會判斷(判斷的程式在文章後段)是否登入,否的話就return登入畫面
另一個是填妥帳密後接收Post資料並做處理
public ActionResult Logon()
{
if(_LogonStatus.isSigned())
{
return Content("PASS");
}
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Logon(FormCollection LogonCollection)
{
var UserName = LogonCollection["UserName"].ifNulltoEmpty();
var Password = LogonCollection["Password"].ifNulltoEmpty();
// 登入的密碼(以 SHA1 加密)
//var PasswordSHA = FormsAuthentication.HashPasswordForStoringInConfigFile(Password, "SHA1");
//這一條是去資料庫抓取輸入的帳號密碼的方法請自行實做
//var myAcc = account.GetSingleAccount(acc, Password);
//做一個假的範例用
var myAcc = new MyAccount(UserName, Password);
// 登入時清空所有 Session 資料
Session.RemoveAll();
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
myAcc.UserName,//你想要存放在 User.Identy.Name 的值,通常是使用者帳號
DateTime.Now,
DateTime.Now.AddMinutes(30),
false,//將管理者登入的 Cookie 設定成 Session Cookie
myAcc.Rank.ToString(),//userdata看你想存放啥
FormsAuthentication.FormsCookiePath);
string encTicket = FormsAuthentication.Encrypt(ticket);
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
return RedirectToAction("TestIsLogon", "Home");
//return View();
}
接著做兩個測試的
第一個
建一個測試用的ActionResult 命名為TestIsLogon 在上面加上attribute [Authorize]
[Authorize]
public ActionResult TestIsLogon()
{
return Content("PASS");
}
測試在未登入成功的情況下
測試在登入成功的情況下
第二個
先製作一段驗證登入的程式
namespace tryUserLogon.Extensions
{
public class LogonStatus
{
public bool isSigned() {
var context = HttpContext.Current;
if(context.User != null)
{
var formIdentify = context.User.Identity as FormsIdentity;
bool IsAuthenticated = context.User.Identity.IsAuthenticated;
if (formIdentify != null && IsAuthenticated)
{
return true;
}
}
return false;
}
}
}
在Controller中先New出LogonStatus物件,然後再index 中測試看看
public class HomeController : Controller
{
LogonStatus _LogonStatus = new LogonStatus(); //<--先NEW出LogonStatus物件
public ActionResult Index()
{
ViewData["IsAuthenticated"] = "未登入";
if (_LogonStatus.isSigned())
{
ViewData["IsAuthenticated"] = "已登入";
}
return View();
}
}
未登入
已登入
這是一段自己客製的擴充方法
namespace tryUserLogon.Extensions
{
public static class NulltoEmptyExtension
{
public static string ifNulltoEmpty(this string str)
{
return str ?? "";
}
}
}
範例檔:
https://bitbucket.org/yu_allen/logonformsauthenticationexercise