這其實是一個比較簡單的問題,但往往挺容易被忽略,這次我們在推廣我們的互聯網平台的時候就吃了這么一個大虧。 一般用戶注冊過程中,前端注冊往往會檢驗用戶名、昵稱是否已存在,甚至驗證碼是否匹配,我們都可以用Remote的驗證很方便的解決。
直接上關鍵代碼:
public class RegisterModel
{
[Required(ErrorMessage = " *郵箱地址不能為空 ")]
[DataType(DataType.EmailAddress)]
[RegularExpression( @" ^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$ ", ErrorMessage = " *請輸入正確的郵箱格式 ")]
[ Remote( " IsExistEmail ", " Validator ",ErrorMessage= " *該郵箱地址已經被注冊過 ")]
public string email { get; set; }
[Required(ErrorMessage = " *郵箱地址不能為空 ")]
[DataType(DataType.EmailAddress)]
[RegularExpression( @" ^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$ ", ErrorMessage = " *請輸入正確的郵箱格式 ")]
[ Remote( " IsExistEmail ", " Validator ",ErrorMessage= " *該郵箱地址已經被注冊過 ")]
public string email { get; set; }
...
}
///
<summary>
/// 驗證該EMail賬戶是否已經被注冊過了
/// </summary>
/// <param name="email"></param>
/// <returns></returns>
public JsonResult IsExistEmail( string email)
{
bool valid = false;
if (!AccountServices.IsExistMail(email))
valid = true;
return Json(valid,JsonRequestBehavior.AllowGet);
}
/// 驗證該EMail賬戶是否已經被注冊過了
/// </summary>
/// <param name="email"></param>
/// <returns></returns>
public JsonResult IsExistEmail( string email)
{
bool valid = false;
if (!AccountServices.IsExistMail(email))
valid = true;
return Json(valid,JsonRequestBehavior.AllowGet);
}
前端的代碼如下:
@Html.TextBoxFor(m => m.email)
@Html.ValidationMessageFor(m => m.email)
@Html.ValidationMessageFor(m => m.email)
代碼很簡單,我想大家都很容易懂,但問題在哪里呢?
問題就是注冊完成后,如果你直接點瀏覽器后退,就能繞開這個驗證機制,因為驗證通過這個過程被緩存起來了。
這樣就很容易在后端出現冗余數據,甚至搞亂程序的業務規則,當然健壯的程序會在業務層再次驗證是否存在email,存在則拋出異常,但往往這是避免惡意注冊和攻擊之類的,返回到用戶這邊是出錯頁面,非常的不友好。此類問題在注冊碼等場景上問題更大,明明用戶輸入的是正確的驗證碼,由於緩存了之前的,所以怎么輸都不對,從而讓這些用戶流失,所以還是要從本源上去解決:
解決思路其實很簡單:你緩存是吧,我不讓你緩存不就行了?ValidatorController中代碼如下:
using System.Web.UI;
/// < summary >
/// 驗證該EMail賬戶是否已經被注冊過了
/// </ summary >
/// < param name ="email" ></ param >
/// < returns ></ returns >
[OutputCache(Location = OutputCacheLocation.None, NoStore = true)] //清除緩存
public JsonResult IsExistEmail(string email)
{
bool valid = false;
if (!AccountServices.IsExistMail(email))
valid = true;
return Json(valid,JsonRequestBehavior.AllowGet);
}
/// < summary >
/// 驗證該EMail賬戶是否已經被注冊過了
/// </ summary >
/// < param name ="email" ></ param >
/// < returns ></ returns >
[OutputCache(Location = OutputCacheLocation.None, NoStore = true)] //清除緩存
public JsonResult IsExistEmail(string email)
{
bool valid = false;
if (!AccountServices.IsExistMail(email))
valid = true;
return Json(valid,JsonRequestBehavior.AllowGet);
}
到此,這個場景下的問題可以解決,因為想讓大家更從實際場景的思維方式去考慮問題,寫的有點羅嗦了,請見諒!